Skip to content

Commit

Permalink
Hh 77606 create poa endpoint (#16132)
Browse files Browse the repository at this point in the history
* create poa service and endpoint

* wip

* create #get_power_of_attorney in BenefitsClaims::Service

* refactor PowerOfAttorneyController

* delete RepresentationManagement::PowerOfAttorney::Service

* create power_of_attorney route

* add test for BenefitsClaims::Service #get_power_of_attorney

* add new vcr cassette for power_of_attorney (must be updated)

* write request specs for PowerOfAttorneyController

* remove email from base serializer and add it to rep serializer

* delete 'PowerOfAttorneyController', type: :request spec

* create RepresentationManagement::V0::PowerOfAttorneyController, type: :controller spec instead

* update endpoint response

* formatting

* add more tests, refactor

* add serializer tests

* add error handling to PowerOfAttorneyController #index

* update icn used in testing poa endpoint

* record vcr

* remove settings

* convert dig args to strings

* order rep query by created_at DESC

* correct the test name

* fix failing tests

* use #order in #find_representative

* stub #order in test

* remove private tests

* refactor PowerOfAttorneyController

* wip

* add another test for rep poa response

* refactor controller and add empty response vcr

* add test for lighthouse responding with 422

* add request spec test for lighthouse responding with 422

* remove benefits claims service poa 422 response test

---------

Co-authored-by: Jonathan VanCourt <[email protected]>
  • Loading branch information
holdenhinkle and jvcAdHoc authored Apr 8, 2024
1 parent 2b073e4 commit 62e01b6
Show file tree
Hide file tree
Showing 13 changed files with 560 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/lighthouse/benefits_claims/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ def get_claim(id, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, opt
raise BenefitsClaims::ServiceException.new(e.response), 'Lighthouse Error'
end

def get_power_of_attorney(lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {})
config.get("#{@icn}/power-of-attorney", lighthouse_client_id, lighthouse_rsa_key_path, options).body
rescue Faraday::TimeoutError
raise BenefitsClaims::ServiceException.new({ status: 504 }), 'Lighthouse Error'
rescue Faraday::ClientError, Faraday::ServerError => e
raise BenefitsClaims::ServiceException.new(e.response), 'Lighthouse Error'
end

def submit5103(user, id, options = {})
params = {}
is_dependent = SponsorResolver.dependent?(user)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# frozen_string_literal: true

require 'lighthouse/benefits_claims/service'

module RepresentationManagement
module V0
class PowerOfAttorneyController < ApplicationController
service_tag 'representation-management'

def index
@active_poa = lighthouse_service.get_power_of_attorney

if @active_poa.blank? || record.blank?
render json: { data: {} }, status: :ok
else
render json: record, serializer:, status: :ok
end
end

private

def lighthouse_service
BenefitsClaims::Service.new(icn)
end

def icn
@current_user&.icn
end

def poa_code
@poa_code ||= @active_poa.dig('data', 'attributes', 'code')
end

def poa_type
@poa_type ||= @active_poa.dig('data', 'type')
end

def record
return @record if defined? @record

@record ||= if poa_type == 'organization'
organization
else
representative
end
end

def serializer
if poa_type == 'organization'
RepresentationManagement::PowerOfAttorney::OrganizationSerializer
else
RepresentationManagement::PowerOfAttorney::RepresentativeSerializer
end
end

def organization
Veteran::Service::Organization.find_by(poa: poa_code)
end

def representative
Veteran::Service::Representative.where('? = ANY(poa_codes)', poa_code).order(created_at: :desc).first
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module RepresentationManagement
module PowerOfAttorney
class BaseSerializer < ActiveModel::Serializer
attribute :address_line1
attribute :address_line2
attribute :address_line3
attribute :address_type
attribute :city
attribute :country_name
attribute :country_code_iso3
attribute :province
attribute :international_postal_code
attribute :state_code
attribute :zip_code
attribute :zip_suffix
attribute :phone
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module RepresentationManagement
module PowerOfAttorney
class OrganizationSerializer < BaseSerializer
attribute :type
attribute :name

def type
'organization'
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module RepresentationManagement
module PowerOfAttorney
class RepresentativeSerializer < BaseSerializer
attribute :type
attribute :name
attribute :email

def type
'representative'
end

def name
object.full_name
end

def phone
object.phone_number
end
end
end
end
1 change: 1 addition & 0 deletions modules/representation_management/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
RepresentationManagement::Engine.routes.draw do
namespace :v0, defaults: { format: 'json' } do
resources :flag_accredited_representatives, only: %i[create]
resources :power_of_attorney, only: %i[index]
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'RepresentationManagement::V0::PowerOfAttorneyController', type: :request do
let(:index_path) { '/representation_management/v0/power_of_attorney' }
let(:user) { create(:user, :loa3) }

describe 'index' do
context 'with a signed in user' do
before do
sign_in_as(user)
end

context 'when an organization is the active poa' do
let(:org_poa) { 'og1' }
let!(:organization) { create(:organization, poa: org_poa) }

it 'returns the expected organization response' do
lh_response = {
'data' => {
'type' => 'organization',
'attributes' => {
'code' => org_poa
}
}
}
allow_any_instance_of(BenefitsClaims::Service)
.to receive(:get_power_of_attorney)
.and_return(lh_response)

get index_path

response_body = JSON.parse(response.body)

expect(response).to have_http_status(:ok)
expect(response_body['data']['id']).to eq(org_poa)
end
end

context 'when a representative is the active poa' do
let(:rep_poa) { 'rp1' }
let(:registration_number) { '12345' }
let!(:representative) do
create(:representative,
representative_id: registration_number, poa_codes: [rep_poa])
end

it 'returns the expected representative response' do
lh_response = {
'data' => {
'type' => 'individual',
'attributes' => {
'code' => rep_poa
}
}
}
allow_any_instance_of(BenefitsClaims::Service)
.to receive(:get_power_of_attorney)
.and_return(lh_response)

get index_path

response_body = JSON.parse(response.body)

expect(response).to have_http_status(:ok)
expect(response_body['data']['id']).to eq(registration_number)
end
end

context 'when there is no active poa' do
it 'returns the expected empty response' do
lh_response = {
'data' => {}
}
allow_any_instance_of(BenefitsClaims::Service)
.to receive(:get_power_of_attorney)
.and_return(lh_response)

get index_path

response_body = JSON.parse(response.body)

expect(response).to have_http_status(:ok)
expect(response_body['data']).to eq({})
end
end

context 'when the poa record is not found in the database' do
it 'returns the expected empty response' do
lh_response = {
'data' => {
'type' => 'organization',
'attributes' => {
'code' => 'abc'
}
}
}
allow_any_instance_of(BenefitsClaims::Service)
.to receive(:get_power_of_attorney)
.and_return(lh_response)

get index_path

response_body = JSON.parse(response.body)

expect(response).to have_http_status(:ok)
expect(response_body['data']).to eq({})
end
end

context 'when the service encounters an unprocessable entity error' do
it 'returns a 422/unprocessable_entity status' do
allow_any_instance_of(BenefitsClaims::Service)
.to receive(:get_power_of_attorney)
.and_raise(Common::Exceptions::UnprocessableEntity)

get index_path

expect(response).to have_http_status(:unprocessable_entity)
end
end
end

context 'without a signed in user' do
describe 'GET #index' do
it 'returns a 401/unauthorized status' do
get index_path

expect(response).to have_http_status(:unauthorized)
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'BaseSerializer' do
before do
create(:organization, poa: 'og1')
create(:representative, representative_id: '123', poa_codes: ['rp1'])
end

def representative
Veteran::Service::Representative.find('123')
end

def organization
Veteran::Service::Organization.find('og1')
end

def assert_attributes(attributes)
expect(attributes.keys).to eq(%w[address_line1
address_line2
address_line3
address_type
city
country_name
country_code_iso3
province
international_postal_code
state_code
zip_code
zip_suffix
phone])
end

it 'can serialize a representative' do
result = serialize(representative, serializer_class: RepresentationManagement::PowerOfAttorney::BaseSerializer)
attributes = JSON.parse(result)['data']['attributes']
assert_attributes(attributes)
end

it 'can serialize an organization' do
result = serialize(organization, serializer_class: RepresentationManagement::PowerOfAttorney::BaseSerializer)
attributes = JSON.parse(result)['data']['attributes']
assert_attributes(attributes)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'OrganizationSerializer' do
before do
create(:organization, poa: 'og1')
end

def organization
Veteran::Service::Organization.find('og1')
end

it 'can serialize an organization' do
result = serialize(organization,
serializer_class: RepresentationManagement::PowerOfAttorney::OrganizationSerializer)
attributes = JSON.parse(result)['data']['attributes']

expect(attributes.keys).to eq(%w[address_line1
address_line2
address_line3
address_type
city
country_name
country_code_iso3
province
international_postal_code
state_code
zip_code
zip_suffix
phone
type
name])
end
end
Loading

0 comments on commit 62e01b6

Please sign in to comment.