From 16d1459d6f70726728c990e0e1699d9c5987edc5 Mon Sep 17 00:00:00 2001 From: Oren Mittman Date: Fri, 7 Feb 2025 17:37:13 -0500 Subject: [PATCH] [ARP - lower camel responses - 2] camel case POA form persistence (#20622) * [ARP] camel case POA form persistence * lint fixes * [ARP - lower camel responses - 3] handle camel params in ARP IPF controller (#20623) * [ARP] handle camel params in ARP IPF controller * [ARP - lower camel responses - 4] camel response in ARP users controller (#20624) * [ARP] camel response in ARP users controller * [ARP - lower camel responses - 5] bypass olive branch (#20625) * [ARP] bypass olive branch * lint fixes --- .../v0/in_progress_forms_controller.rb | 2 +- .../v0/representative_users_controller.rb | 14 ++-- .../power_of_attorney_form.rb | 76 ++++++++--------- .../initializers/bypass_olive_branch.rb | 40 +++++++++ .../spec/factories/power_of_attorney_form.rb | 84 +++++++++---------- .../spec/factories/representative_user.rb | 6 +- .../bypass_olive_branch_spec.rb | 48 +++++++++++ .../v0/in_progress_forms_spec.rb | 25 +++--- ...ndent_claimant_power_of_attorney_form.json | 36 ++++---- ...teran_claimant_power_of_attorney_form.json | 24 +++--- .../v0/user_spec.rb | 23 ++--- 11 files changed, 230 insertions(+), 148 deletions(-) create mode 100644 modules/accredited_representative_portal/config/initializers/bypass_olive_branch.rb create mode 100644 modules/accredited_representative_portal/spec/requests/accredited_representative_portal/bypass_olive_branch_spec.rb diff --git a/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/in_progress_forms_controller.rb b/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/in_progress_forms_controller.rb index 52a29d5849f..aedc907fb75 100644 --- a/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/in_progress_forms_controller.rb +++ b/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/in_progress_forms_controller.rb @@ -8,7 +8,7 @@ class InProgressFormsController < ApplicationController def update form = find_form || build_form form.update!( - form_data: params[:form_data], + form_data: params[:formData], metadata: params[:metadata] ) diff --git a/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/representative_users_controller.rb b/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/representative_users_controller.rb index 2625edcdf93..91e9e84b347 100644 --- a/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/representative_users_controller.rb +++ b/modules/accredited_representative_portal/app/controllers/accredited_representative_portal/v0/representative_users_controller.rb @@ -11,18 +11,18 @@ def show # serialization layer. render json: { account: { - account_uuid: @current_user.user_account_uuid + accountUuid: @current_user.user_account_uuid }, profile: { - first_name: @current_user.first_name, - last_name: @current_user.last_name, + firstName: @current_user.first_name, + lastName: @current_user.last_name, verified: @current_user.user_account.verified?, - sign_in: { - service_name: @current_user.sign_in[:service_name] + signIn: { + serviceName: @current_user.sign_in[:service_name] } }, - prefills_available: [], - in_progress_forms: + prefillsAvailable: [], + inProgressForms: in_progress_forms } end diff --git a/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_form.rb b/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_form.rb index a60fb2b2b24..87eaeb75b2a 100644 --- a/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_form.rb +++ b/modules/accredited_representative_portal/app/models/accredited_representative_portal/power_of_attorney_form.rb @@ -49,8 +49,8 @@ def set_location return unless address self.claimant_city = address['city'] - self.claimant_state_code = address['state_code'] - self.claimant_zip_code = address['zip_code'] + self.claimant_state_code = address['stateCode'] + self.claimant_zip_code = address['zipCode'] end def data_must_comply_with_schema @@ -83,11 +83,11 @@ def data_must_comply_with_schema "authorizations": { "type": "object", "properties": { - "record_disclosure": { + "recordDisclosure": { "type": "boolean", "example": true }, - "record_disclosure_limitations": { + "recordDisclosureLimitations": { "type": "array", "items": { "type": "string", @@ -105,15 +105,15 @@ def data_must_comply_with_schema "SICKLE_CELL" ] }, - "address_change": { + "addressChange": { "type": "boolean", "example": false } }, "required": [ - "record_disclosure", - "record_disclosure_limitations", - "address_change" + "recordDisclosure", + "recordDisclosureLimitations", + "addressChange" ] }, "dependent": { @@ -144,11 +144,11 @@ def data_must_comply_with_schema "address": { "type": "object", "properties": { - "address_line1": { + "addressLine1": { "type": "string", "example": "123 Main St" }, - "address_line2": { + "addressLine2": { "type": ["string", "null"], "example": "Apt 1" }, @@ -156,7 +156,7 @@ def data_must_comply_with_schema "type": "string", "example": "Springfield" }, - "state_code": { + "stateCode": { "type": "string", "example": "IL" }, @@ -164,26 +164,26 @@ def data_must_comply_with_schema "type": "string", "example": "US" }, - "zip_code": { + "zipCode": { "type": "string", "example": "62704" }, - "zip_code_suffix": { + "zipCodeSuffix": { "type": ["string", "null"], "example": "6789" } }, "required": [ - "address_line1", - "address_line2", + "addressLine1", + "addressLine2", "city", - "state_code", + "stateCode", "country", - "zip_code", - "zip_code_suffix" + "zipCode", + "zipCodeSuffix" ] }, - "date_of_birth": { + "dateOfBirth": { "type": "string", "format": "date", "example": "1980-12-31" @@ -204,7 +204,7 @@ def data_must_comply_with_schema "required": [ "name", "address", - "date_of_birth", + "dateOfBirth", "relationship", "phone", "email" @@ -238,11 +238,11 @@ def data_must_comply_with_schema "address": { "type": "object", "properties": { - "address_line1": { + "addressLine1": { "type": "string", "example": "123 Main St" }, - "address_line2": { + "addressLine2": { "type": ["string", "null"], "example": "Apt 1" }, @@ -250,7 +250,7 @@ def data_must_comply_with_schema "type": "string", "example": "Springfield" }, - "state_code": { + "stateCode": { "type": "string", "example": "IL" }, @@ -258,43 +258,43 @@ def data_must_comply_with_schema "type": "string", "example": "US" }, - "zip_code": { + "zipCode": { "type": "string", "example": "62704" }, - "zip_code_suffix": { + "zipCodeSuffix": { "type": ["string", "null"], "example": "6789" } }, "required": [ - "address_line1", - "address_line2", + "addressLine1", + "addressLine2", "city", - "state_code", + "stateCode", "country", - "zip_code", - "zip_code_suffix" + "zipCode", + "zipCodeSuffix" ] }, "ssn": { "type": "string", "example": "123456789" }, - "va_file_number": { + "vaFileNumber": { "type": ["string", "null"], "example": "123456789" }, - "date_of_birth": { + "dateOfBirth": { "type": "string", "format": "date", "example": "1980-12-31" }, - "service_number": { + "serviceNumber": { "type": ["string", "null"], "example": "123456789" }, - "service_branch": { + "serviceBranch": { "type": ["string", "null"], "enum": [ "ARMY", @@ -321,10 +321,10 @@ def data_must_comply_with_schema "name", "address", "ssn", - "va_file_number", - "date_of_birth", - "service_number", - "service_branch", + "vaFileNumber", + "dateOfBirth", + "serviceNumber", + "serviceBranch", "phone", "email" ] diff --git a/modules/accredited_representative_portal/config/initializers/bypass_olive_branch.rb b/modules/accredited_representative_portal/config/initializers/bypass_olive_branch.rb new file mode 100644 index 00000000000..67e859e78d0 --- /dev/null +++ b/modules/accredited_representative_portal/config/initializers/bypass_olive_branch.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module AccreditedRepresentativePortal + ## + # `olive_branch` transforms (a) request and (b) response payloads. + # + # (a) It deeply transforms request and query param keys. + # At times it is convenient for params to act as snake-cased setters at a Ruby + # interface, but not always. Form resources are a possible example where not. + # + # For now, let's wait to encounter the cases where we really want this + # convenience. If we do encounter some, we may discover that we want a more + # explicit and collocated way to opt in. + # + # (b) It reloads the response from JSON, deeply transforms keys, and dumps + # back to JSON. + # This is superfluous because our serialization layer `jsonapi-serializer` + # already has a configuration option for key casing. This realizes our desired + # casing the one and only time it is visiting an object during serialization. + # + module BypassOliveBranch + def call(env) + exclude_arp_route?(env) ? @app.call(env) : super + end + + private + + ARP_PATH_INFO_PREFIX = '/accredited_representative_portal' + + def exclude_arp_route?(env) + env['PATH_INFO'].to_s.start_with?(ARP_PATH_INFO_PREFIX) + end + end +end + +module OliveBranch + class Middleware + prepend AccreditedRepresentativePortal::BypassOliveBranch + end +end diff --git a/modules/accredited_representative_portal/spec/factories/power_of_attorney_form.rb b/modules/accredited_representative_portal/spec/factories/power_of_attorney_form.rb index 48cebc2c0f3..ca3b353c1ea 100644 --- a/modules/accredited_representative_portal/spec/factories/power_of_attorney_form.rb +++ b/modules/accredited_representative_portal/spec/factories/power_of_attorney_form.rb @@ -2,9 +2,9 @@ dependent_claimant_data_hash = { authorizations: { - record_disclosure: true, - record_disclosure_limitations: [], - address_change: true + recordDisclosure: true, + recordDisclosureLimitations: [], + addressChange: true }, dependent: { name: { @@ -13,15 +13,15 @@ last: 'Doe' }, address: { - address_line1: '123 Main St', - address_line2: 'Apt 1', + addressLine1: '123 Main St', + addressLine2: 'Apt 1', city: 'Springfield', - state_code: 'IL', + stateCode: 'IL', country: 'US', - zip_code: '62704', - zip_code_suffix: '6789' + zipCode: '62704', + zipCodeSuffix: '6789' }, - date_of_birth: '1980-12-31', + dateOfBirth: '1980-12-31', relationship: 'Spouse', phone: '1234567890', email: 'veteran@example.com' @@ -33,19 +33,19 @@ last: 'Doe' }, address: { - address_line1: '123 Main St', - address_line2: 'Apt 1', + addressLine1: '123 Main St', + addressLine2: 'Apt 1', city: 'Springfield', - state_code: 'IL', + stateCode: 'IL', country: 'US', - zip_code: '62704', - zip_code_suffix: '6789' + zipCode: '62704', + zipCodeSuffix: '6789' }, ssn: '123456789', - va_file_number: '123456789', - date_of_birth: '1980-12-31', - service_number: '123456789', - service_branch: 'ARMY', + vaFileNumber: '123456789', + dateOfBirth: '1980-12-31', + serviceNumber: '123456789', + serviceBranch: 'ARMY', phone: '1234567890', email: 'veteran@example.com' } @@ -53,12 +53,12 @@ veteran_claimant_data_hash = { authorizations: { - record_disclosure: true, - record_disclosure_limitations: %w[ + recordDisclosure: true, + recordDisclosureLimitations: %w[ HIV DRUG_ABUSE ], - address_change: true + addressChange: true }, dependent: nil, veteran: { @@ -68,19 +68,19 @@ last: 'Doe' }, address: { - address_line1: '123 Main St', - address_line2: 'Apt 1', + addressLine1: '123 Main St', + addressLine2: 'Apt 1', city: 'Springfield', - state_code: 'IL', + stateCode: 'IL', country: 'US', - zip_code: '62704', - zip_code_suffix: '6789' + zipCode: '62704', + zipCodeSuffix: '6789' }, ssn: '123456789', - va_file_number: '123456789', - date_of_birth: '1980-12-31', - service_number: '123456789', - service_branch: 'ARMY', + vaFileNumber: '123456789', + dateOfBirth: '1980-12-31', + serviceNumber: '123456789', + serviceBranch: 'ARMY', phone: '1234567890', email: 'veteran@example.com' } @@ -94,14 +94,14 @@ data_hash do { authorizations: { - record_disclosure: Faker::Boolean.boolean, - record_disclosure_limitations: %w[ + recordDisclosure: Faker::Boolean.boolean, + recordDisclosureLimitations: %w[ ALCOHOLISM DRUG_ABUSE HIV SICKLE_CELL ].select { rand < 0.5 }, - address_change: Faker::Boolean.boolean + addressChange: Faker::Boolean.boolean }, dependent: nil, veteran: { @@ -111,19 +111,19 @@ last: Faker::Name.first_name }, address: { - address_line1: Faker::Address.street_address, - address_line2: nil, + addressLine1: Faker::Address.street_address, + addressLine2: nil, city: Faker::Address.city, - state_code: Faker::Address.state_abbr, + stateCode: Faker::Address.state_abbr, country: 'US', - zip_code: Faker::Address.zip_code, - zip_code_suffix: nil + zipCode: Faker::Address.zip_code, + zipCodeSuffix: nil }, ssn: Faker::Number.number(digits: 9).to_s, - va_file_number: Faker::Number.number(digits: 9).to_s, - date_of_birth: Faker::Date.birthday(min_age: 21, max_age: 100).to_s, - service_number: Faker::Number.number(digits: 9).to_s, - service_branch: %w[ + vaFileNumber: Faker::Number.number(digits: 9).to_s, + dateOfBirth: Faker::Date.birthday(min_age: 21, max_age: 100).to_s, + serviceNumber: Faker::Number.number(digits: 9).to_s, + serviceBranch: %w[ ARMY NAVY AIR_FORCE diff --git a/modules/accredited_representative_portal/spec/factories/representative_user.rb b/modules/accredited_representative_portal/spec/factories/representative_user.rb index d948597b038..eef4eeb1d5e 100644 --- a/modules/accredited_representative_portal/spec/factories/representative_user.rb +++ b/modules/accredited_representative_portal/spec/factories/representative_user.rb @@ -39,7 +39,11 @@ { form_id: evaluator.in_progress_form_id, user_account: user.user_account, - user_uuid: user.uuid + user_uuid: user.uuid, + metadata: { + version: 1, + returnUrl: 'foo.com' + } } ) end diff --git a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/bypass_olive_branch_spec.rb b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/bypass_olive_branch_spec.rb new file mode 100644 index 00000000000..edaddc15cfe --- /dev/null +++ b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/bypass_olive_branch_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'rails_helper' + +class BypassOliveBranchTestController < ActionController::API + def arp = render json: {} + def normal = render json: {} +end + +RSpec.describe AccreditedRepresentativePortal::BypassOliveBranch, type: :request do + subject do + get "#{path_prefix}/bypass_olive_branch_test", headers: { + 'X-Key-Inflection' => 'camel', + 'Content-Type' => 'application/json' + } + end + + before(:all) do + Rails.application.routes.draw do + get '/accredited_representative_portal/bypass_olive_branch_test', to: 'bypass_olive_branch_test#arp' + get '/bypass_olive_branch_test', to: 'bypass_olive_branch_test#normal' + end + end + + after(:all) do + Rails.application.reload_routes! + end + + context 'when the request is for an accredited representative portal route' do + let(:path_prefix) { '/accredited_representative_portal' } + + it 'bypasses OliveBranch processing' do + expect(OliveBranch::Transformations).not_to receive(:underscore_params) + expect(OliveBranch::Transformations).not_to receive(:transform) + subject + end + end + + context 'when the request is for a normal route' do + let(:path_prefix) { '' } + + it 'applies OliveBranch processing' do + expect(OliveBranch::Transformations).to receive(:underscore_params) + expect(OliveBranch::Transformations).to receive(:transform) + subject + end + end +end diff --git a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/in_progress_forms_spec.rb b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/in_progress_forms_spec.rb index c6b81b8dd60..57fcbf04fae 100644 --- a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/in_progress_forms_spec.rb +++ b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/in_progress_forms_spec.rb @@ -22,7 +22,11 @@ :in_progress_form, user_uuid: representative_user.uuid, form_data: { field: 'value' }, - form_id: + form_id:, + metadata: { + version: 1, + returnUrl: 'foo.com' + } ) get("/accredited_representative_portal/v0/in_progress_forms/#{form_id}") @@ -33,14 +37,7 @@ }, 'metadata' => { 'version' => 1, - 'return_url' => 'foo.com', - 'submission' => { - 'status' => false, - 'error_message' => false, - 'id' => false, - 'timestamp' => false, - 'has_attempted_submit' => false - }, + 'returnUrl' => 'foo.com', 'createdAt' => 1_646_370_367, 'expiresAt' => 1_651_554_367, 'lastUpdated' => 1_646_370_367, @@ -57,7 +54,7 @@ put( "/accredited_representative_portal/v0/in_progress_forms/#{form_id}", - params: { 'form_data' => { another_field: 'foo' } }.to_json, + params: { 'formData' => { anotherField: 'foo' } }.to_json, headers: ) @@ -85,7 +82,7 @@ expect(parsed_response).to eq( { 'formData' => { - 'another_field' => 'foo' + 'anotherField' => 'foo' }, 'metadata' => { 'createdAt' => 1_646_456_767, @@ -101,7 +98,7 @@ put( "/accredited_representative_portal/v0/in_progress_forms/#{form_id}", - params: { 'form_data' => { another_field: 'foo', sample_field: 'sample' } }.to_json, + params: { 'formData' => { anotherField: 'foo', sampleField: 'sample' } }.to_json, headers: ) @@ -129,8 +126,8 @@ expect(parsed_response).to eq( { 'formData' => { - 'another_field' => 'foo', - 'sample_field' => 'sample' + 'anotherField' => 'foo', + 'sampleField' => 'sample' }, 'metadata' => { 'createdAt' => 1_646_456_767, diff --git a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/dependent_claimant_power_of_attorney_form.json b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/dependent_claimant_power_of_attorney_form.json index 1ab870a1377..2d9fef497bd 100644 --- a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/dependent_claimant_power_of_attorney_form.json +++ b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/dependent_claimant_power_of_attorney_form.json @@ -1,8 +1,8 @@ { "authorizations": { - "record_disclosure": true, - "record_disclosure_limitations": [], - "address_change": true + "recordDisclosure": true, + "recordDisclosureLimitations": [], + "addressChange": true }, "veteran": { "name": { @@ -11,19 +11,19 @@ "last": "Doe" }, "address": { - "address_line1": "123 Main St", - "address_line2": "Apt 1", + "addressLine1": "123 Main St", + "addressLine2": "Apt 1", "city": "Springfield", - "state_code": "IL", + "stateCode": "IL", "country": "US", - "zip_code": "62704", - "zip_code_suffix": "6789" + "zipCode": "62704", + "zipCodeSuffix": "6789" }, "ssn": "123456789", - "va_file_number": "123456789", - "date_of_birth": "1980-12-31", - "service_number": "123456789", - "service_branch": "ARMY", + "vaFileNumber": "123456789", + "dateOfBirth": "1980-12-31", + "serviceNumber": "123456789", + "serviceBranch": "ARMY", "phone": "1234567890", "email": "veteran@example.com" }, @@ -34,15 +34,15 @@ "last": "Doe" }, "address": { - "address_line1": "123 Main St", - "address_line2": "Apt 1", + "addressLine1": "123 Main St", + "addressLine2": "Apt 1", "city": "Springfield", - "state_code": "IL", + "stateCode": "IL", "country": "US", - "zip_code": "62704", - "zip_code_suffix": "6789" + "zipCode": "62704", + "zipCodeSuffix": "6789" }, - "date_of_birth": "1980-12-31", + "dateOfBirth": "1980-12-31", "relationship": "Spouse", "phone": "1234567890", "email": "veteran@example.com" diff --git a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/veteran_claimant_power_of_attorney_form.json b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/veteran_claimant_power_of_attorney_form.json index e270c3a2ed5..0c943131d96 100644 --- a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/veteran_claimant_power_of_attorney_form.json +++ b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/power_of_attorney_requests_spec/responses/veteran_claimant_power_of_attorney_form.json @@ -1,11 +1,11 @@ { "authorizations": { - "record_disclosure": true, - "record_disclosure_limitations": [ + "recordDisclosure": true, + "recordDisclosureLimitations": [ "HIV", "DRUG_ABUSE" ], - "address_change": true + "addressChange": true }, "claimant": { "name": { @@ -14,19 +14,19 @@ "last": "Doe" }, "address": { - "address_line1": "123 Main St", - "address_line2": "Apt 1", + "addressLine1": "123 Main St", + "addressLine2": "Apt 1", "city": "Springfield", - "state_code": "IL", + "stateCode": "IL", "country": "US", - "zip_code": "62704", - "zip_code_suffix": "6789" + "zipCode": "62704", + "zipCodeSuffix": "6789" }, "ssn": "123456789", - "va_file_number": "123456789", - "date_of_birth": "1980-12-31", - "service_number": "123456789", - "service_branch": "ARMY", + "vaFileNumber": "123456789", + "dateOfBirth": "1980-12-31", + "serviceNumber": "123456789", + "serviceBranch": "ARMY", "phone": "1234567890", "email": "veteran@example.com" } diff --git a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/user_spec.rb b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/user_spec.rb index 1afe74794f0..2b966b3dc59 100644 --- a/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/user_spec.rb +++ b/modules/accredited_representative_portal/spec/requests/accredited_representative_portal/v0/user_spec.rb @@ -46,30 +46,23 @@ expect(parsed_response).to eq( { 'account' => { - 'account_uuid' => user.user_account.id + 'accountUuid' => user.user_account.id }, 'profile' => { - 'first_name' => first_name, - 'last_name' => last_name, + 'firstName' => first_name, + 'lastName' => last_name, 'verified' => true, - 'sign_in' => { - 'service_name' => sign_in_service_name + 'signIn' => { + 'serviceName' => sign_in_service_name } }, - 'prefills_available' => [], - 'in_progress_forms' => [ + 'prefillsAvailable' => [], + 'inProgressForms' => [ { 'form' => in_progress_form_id, 'metadata' => { 'version' => 1, - 'return_url' => 'foo.com', - 'submission' => { - 'status' => false, - 'error_message' => false, - 'id' => false, - 'timestamp' => false, - 'has_attempted_submit' => false - }, + 'returnUrl' => 'foo.com', 'createdAt' => Time.current.to_i, 'expiresAt' => 60.days.from_now.to_i, 'lastUpdated' => Time.current.to_i,