-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue# 98709 & 98710 POA Request List and Detail endpoints #19967
Changes from 4 commits
a58b23b
e5c36db
e7856e0
c7eebf8
e3032d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,53 +3,16 @@ | |
module AccreditedRepresentativePortal | ||
module V0 | ||
class PowerOfAttorneyRequestsController < ApplicationController | ||
POA_REQUEST_ITEM_MOCK_DATA = { | ||
status: 'Pending', | ||
declinedReason: nil, | ||
powerOfAttorneyCode: '091', | ||
submittedAt: '2024-04-30T11:03:17Z', | ||
acceptedOrDeclinedAt: nil, | ||
isAddressChangingAuthorized: false, | ||
isTreatmentDisclosureAuthorized: true, | ||
veteran: { | ||
firstName: 'Jon', | ||
middleName: nil, | ||
lastName: 'Smith', | ||
participantId: '6666666666666' | ||
}, | ||
representative: { | ||
email: '[email protected]', | ||
firstName: 'Jane', | ||
lastName: 'Doe' | ||
}, | ||
claimant: { | ||
firstName: 'Sam', | ||
lastName: 'Smith', | ||
participantId: '777777777777777', | ||
relationshipToVeteran: 'Child' | ||
}, | ||
claimantAddress: { | ||
city: 'Hartford', | ||
state: 'CT', | ||
zip: '06107', | ||
country: 'GU', | ||
militaryPostOffice: nil, | ||
militaryPostalCode: nil | ||
} | ||
}.freeze | ||
|
||
POA_REQUEST_LIST_MOCK_DATA = [ | ||
POA_REQUEST_ITEM_MOCK_DATA, | ||
POA_REQUEST_ITEM_MOCK_DATA, | ||
POA_REQUEST_ITEM_MOCK_DATA | ||
].freeze | ||
|
||
def index | ||
render json: POA_REQUEST_LIST_MOCK_DATA | ||
poa_requests = PowerOfAttorneyRequest.includes(:resolution) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where we want to includes the rest of the object graph to not have N+1 query like the original proof of concept spec shows. So maybe this becomes |
||
render json: PowerOfAttorneyRequestSerializer.new(poa_requests).serializable_hash, status: :ok | ||
end | ||
|
||
def show | ||
render json: POA_REQUEST_ITEM_MOCK_DATA | ||
poa_request = PowerOfAttorneyRequest.includes(:resolution).find(params[:id]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where we want to includes the rest of the object graph to not have N+1 query like the original proof of concept spec shows. So maybe this becomes |
||
render json: PowerOfAttorneyRequestSerializer.new(poa_request).serializable_hash, status: :ok | ||
rescue ActiveRecord::RecordNotFound | ||
render json: { error: 'Record not found' }, status: :not_found | ||
end | ||
end | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
module AccreditedRepresentativePortal | ||
class PowerOfAttorneyRequestResolutionSerializer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow the library's guide for polymorphic relationship instead. |
||
include JSONAPI::Serializer | ||
|
||
attribute :id | ||
|
||
attribute :type do |object| | ||
object.resolving_type.demodulize.underscore.split('_').last | ||
end | ||
Comment on lines
+9
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once we have the polymorphic variants, each of them can hardcode this rather than manipulate the name of the Ruby class. In the end we should get: |
||
|
||
attribute :decision_type, if: proc { |obj| obj.resolving.respond_to?(:type) } do |object| | ||
object.resolving.type | ||
end | ||
|
||
attribute :reason | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reason will only need to be serialized on a declination in the decision serializer variant. |
||
|
||
attribute :creator_id, if: proc { |obj| obj.resolving.respond_to?(:creator_id) } do |object| | ||
object.resolving.creator_id | ||
end | ||
|
||
attribute :created_at do |object| | ||
object.created_at.iso8601 | ||
end | ||
Comment on lines
+23
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How was this serializing without the custom attribute? |
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# frozen_string_literal: true | ||
|
||
module AccreditedRepresentativePortal | ||
class PowerOfAttorneyRequestSerializer | ||
include JSONAPI::Serializer | ||
|
||
attributes :id, :claimant_id | ||
|
||
attribute :created_at do |object| | ||
object.created_at.iso8601 | ||
end | ||
Comment on lines
+9
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How was this getting serialized without the custom attribute? |
||
|
||
attribute :resolution do |object| | ||
next nil if object.resolution.blank? | ||
|
||
AccreditedRepresentativePortal::PowerOfAttorneyRequestResolutionSerializer.new( | ||
object.resolution | ||
).serializable_hash[:data][:attributes] | ||
end | ||
Comment on lines
+13
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we use a relationship serializer? In fact it looks like we want to follow their example here for polymorphism:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't control the structure that way. The result isn't flat like how we want it to be (they get placed under "relationships"). And there doesn't seem to be a way to override the default serialization when using relationships. |
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,47 +4,43 @@ | |
|
||
RSpec.describe AccreditedRepresentativePortal::V0::PowerOfAttorneyRequestsController, type: :request do | ||
let(:test_user) { create(:representative_user) } | ||
let(:poa_request_details_id) { '123' } | ||
let(:poa_request_details_mock_data) do | ||
{ | ||
'status' => 'Pending', | ||
'declinedReason' => nil, | ||
'powerOfAttorneyCode' => '091', | ||
'submittedAt' => '2024-04-30T11:03:17Z', | ||
'acceptedOrDeclinedAt' => nil, | ||
'isAddressChangingAuthorized' => false, | ||
'isTreatmentDisclosureAuthorized' => true, | ||
'veteran' => { 'firstName' => 'Jon', 'middleName' => nil, 'lastName' => 'Smith', | ||
'participantId' => '6666666666666' }, | ||
'representative' => { 'email' => '[email protected]', 'firstName' => 'Jane', 'lastName' => 'Doe' }, | ||
'claimant' => { 'firstName' => 'Sam', 'lastName' => 'Smith', 'participantId' => '777777777777777', | ||
'relationshipToVeteran' => 'Child' }, | ||
'claimantAddress' => { 'city' => 'Hartford', 'state' => 'CT', 'zip' => '06107', 'country' => 'GU', | ||
'militaryPostOffice' => nil, 'militaryPostalCode' => nil } | ||
} | ||
end | ||
let(:poa_request_list_mock_data) do | ||
[poa_request_details_mock_data, poa_request_details_mock_data, poa_request_details_mock_data] | ||
end | ||
let(:poa_request) { create(:power_of_attorney_request) } | ||
let(:poa_requests) { create_list(:power_of_attorney_request, 3) } | ||
|
||
before do | ||
Flipper.enable(:accredited_representative_portal_pilot) | ||
login_as(test_user) | ||
end | ||
|
||
describe 'GET /accredited_representative_portal/v0/power_of_attorney_requests' do | ||
it 'returns the list of a power of attorney request' do | ||
it 'returns the list of power of attorney requests' do | ||
poa_requests | ||
|
||
get('/accredited_representative_portal/v0/power_of_attorney_requests') | ||
|
||
expect(response).to have_http_status(:ok) | ||
expect(JSON.parse(response.body)).to eq(poa_request_list_mock_data) | ||
parsed_response = JSON.parse(response.body) | ||
|
||
expected_response = AccreditedRepresentativePortal::PowerOfAttorneyRequestSerializer | ||
.new(poa_requests) | ||
.serializable_hash | ||
|
||
expect(parsed_response.to_json).to eq(expected_response.to_json) | ||
end | ||
end | ||
|
||
describe 'GET /accredited_representative_portal/v0/power_of_attorney_requests/:id' do | ||
it 'returns the details of a power of attorney request' do | ||
get("/accredited_representative_portal/v0/power_of_attorney_requests/#{poa_request_details_id}") | ||
it 'returns the details of a specific power of attorney request' do | ||
get("/accredited_representative_portal/v0/power_of_attorney_requests/#{poa_request.id}") | ||
|
||
expect(response).to have_http_status(:ok) | ||
expect(JSON.parse(response.body)).to include(poa_request_details_mock_data) | ||
parsed_response = JSON.parse(response.body) | ||
|
||
expected_response = AccreditedRepresentativePortal::PowerOfAttorneyRequestSerializer | ||
.new(poa_request) | ||
.serializable_hash | ||
|
||
expect(parsed_response.to_json).to eq(expected_response.to_json) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative '../../rails_helper' | ||
|
||
RSpec.describe AccreditedRepresentativePortal::PowerOfAttorneyRequestResolutionSerializer, type: :serializer do | ||
describe 'serialization' do | ||
subject { described_class.new(resolution).serializable_hash[:data][:attributes] } | ||
|
||
let(:user) { create(:user_account) } | ||
let(:resolution) do | ||
create(:power_of_attorney_request_resolution, resolving: resolving, reason: 'Did not authorize') | ||
end | ||
|
||
context 'when resolving is a Decision' do | ||
let(:resolving) { create(:power_of_attorney_request_decision, type: 'declination', creator: user) } | ||
|
||
it 'serializes resolution with decision-specific fields' do | ||
expect(subject).to eq( | ||
id: resolution.id, | ||
created_at: resolution.created_at.iso8601, | ||
reason: 'Did not authorize', | ||
type: 'decision', | ||
decision_type: 'declination', | ||
creator_id: user.id | ||
) | ||
end | ||
end | ||
|
||
context 'when resolving is an Expiration' do | ||
let(:resolving) { create(:power_of_attorney_request_expiration) } | ||
|
||
it 'serializes resolution with expiration-specific fields' do | ||
expect(subject).to eq( | ||
id: resolution.id, | ||
created_at: resolution.created_at.iso8601, | ||
reason: 'Did not authorize', | ||
type: 'expiration' | ||
) | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative '../../rails_helper' | ||
|
||
RSpec.describe AccreditedRepresentativePortal::PowerOfAttorneyRequestSerializer, type: :serializer do | ||
describe 'serialization' do | ||
subject { described_class.new(poa_request).serializable_hash[:data][:attributes] } | ||
|
||
let(:claimant) { create(:user_account) } | ||
let(:poa_request) { create(:power_of_attorney_request, claimant: claimant, resolution: resolution) } | ||
|
||
context 'when resolution exists' do | ||
let(:resolution) do | ||
create(:power_of_attorney_request_resolution, | ||
resolving: create(:power_of_attorney_request_decision, type: 'declination')) | ||
end | ||
|
||
it 'serializes POA request with resolution' do | ||
expect(subject).to eq( | ||
id: poa_request.id, | ||
claimant_id: poa_request.claimant_id, | ||
created_at: poa_request.created_at.iso8601, | ||
resolution: { | ||
id: resolution.id, | ||
created_at: resolution.created_at.iso8601, | ||
reason: resolution.reason, | ||
type: 'decision', | ||
decision_type: 'declination', | ||
creator_id: resolution.resolving.creator_id | ||
} | ||
) | ||
end | ||
end | ||
|
||
context 'when resolution is absent' do | ||
let(:resolution) { nil } | ||
|
||
it 'serializes POA request without resolution' do | ||
expect(subject).to eq( | ||
id: poa_request.id, | ||
claimant_id: poa_request.claimant_id, | ||
created_at: poa_request.created_at.iso8601, | ||
resolution: nil | ||
) | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add
.limit(100)
just in case.