Skip to content

Commit

Permalink
(feat): Add serializers for PowerOfAttorneyRequest and Resolution wit…
Browse files Browse the repository at this point in the history
…h specs

- Implement `PowerOfAttorneyRequestSerializer` to handle serialization of power of attorney requests, including nested resolution data.
- Implement `PowerOfAttorneyRequestResolutionSerializer` to serialize resolution details, accommodating various resolution subtypes.
- Add comprehensive specs for both serializers to ensure accurate and dynamic handling of attributes.
- Adjust model factories accordingly
  • Loading branch information
ojbucao authored and nihil2501 committed Dec 21, 2024
1 parent 8d0a081 commit c6e4481
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@ module AccreditedRepresentativePortal
module V0
class PowerOfAttorneyRequestsController < ApplicationController
def index
requests = PowerOfAttorneyRequest.includes(:resolution)
render json: PowerOfAttorneyRequestSerializer.new(requests).serializable_hash, status: :ok
poa_requests = PowerOfAttorneyRequest.includes(:resolution)
render json: PowerOfAttorneyRequestSerializer.new(poa_requests).serializable_hash, status: :ok
end

def show
request = PowerOfAttorneyRequest.includes(:resolution).find(params[:id])
render json: PowerOfAttorneyRequestSerializer.new(request).serializable_hash, status: :ok
poa_request = PowerOfAttorneyRequest.includes(:resolution).find(params[:id])
render json: PowerOfAttorneyRequestSerializer.new(poa_request).serializable_hash, status: :ok
rescue ActiveRecord::RecordNotFound
render json: { error: 'Record not found' }, status: :not_found
end

private

def authenticate; end
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
include JSONAPI::Serializer

attribute :id

attribute :type do |object|
object.resolving_type.demodulize.underscore.split('_').last
end

attribute :decision_type, if: proc { |obj| obj.resolving.respond_to?(:type) } do |object|
object.resolving.type
end

attribute :reason

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
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,15 @@ class PowerOfAttorneyRequestSerializer
attributes :id, :claimant_id

attribute :created_at do |object|
object.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ')
object.created_at.iso8601
end

attribute :resolution do |object|
next nil unless object.resolution
next nil if object.resolution.blank?

{
id: object.resolution.id,
type: object.resolution.resolving_type&.demodulize&.underscore,
created_at: object.resolution.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
reason: object.resolution&.reason,
creator_id: object.resolution.resolving.try(:creator_id)
}.compact
AccreditedRepresentativePortal::PowerOfAttorneyRequestResolutionSerializer.new(
object.resolution
).serializable_hash[:data][:attributes]
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@
id { Faker::Internet.uuid }
association :creator, factory: :user_account
type { 'Approval' }

trait :declination do
type { 'Declination' }
end

trait :approval do
type { 'Approval' }
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
association :claimant, factory: :user_account
id { Faker::Internet.uuid }
created_at { Time.current }

trait :with_resolution do
resolution { create(:power_of_attorney_request_resolution, :with_decision) }
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
.new(poa_requests)
.serializable_hash

expect(deep_stringify(parsed_response)).to eq(deep_stringify(expected_response))
expect(parsed_response.to_json).to eq(expected_response.to_json)
end
end

Expand All @@ -40,22 +40,7 @@
.new(poa_request)
.serializable_hash

expect(deep_stringify(parsed_response)).to eq(deep_stringify(expected_response))
end
end

def deep_stringify(value)
case value
when Hash
value.each_with_object({}) do |(k, v), result|
result[k.to_s] = deep_stringify(v) # Stringify keys and recursively process values
end
when Array
value.map { |v| deep_stringify(v) } # Recursively process arrays
when Symbol
value.to_s # Convert symbols to strings
else
value # Leave other primitives (e.g., strings, numbers, nil) as is
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
@@ -1,75 +1,48 @@
# frozen_string_literal: true

# spec/serializers/power_of_attorney_request_serializer_spec.rb
require 'rails_helper'

RSpec.describe AccreditedRepresentativePortal::PowerOfAttorneyRequestSerializer do
subject { described_class.new(request).serializable_hash[:data][:attributes] }

let(:request) { create(:power_of_attorney_request, created_at: '2024-12-17T00:30:55Z') }

context 'when resolution is nil' do
it 'returns the request without resolution' do
expect(subject).to eq({
id: request.id,
claimant_id: request.claimant_id,
created_at: '2024-12-17T00:30:55.000Z',
resolution: nil
})
end
end

context 'when resolution is an expiration' do
let(:resolution) do
create(:power_of_attorney_request_resolution, :with_expiration, reason: 'Test reason for resolution')
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

before { request.update(resolution: resolution) }

it 'includes resolution details with type expiration and reason' do
expect(subject[:resolution]).to eq({
id: resolution.id,
type: 'power_of_attorney_request_expiration',
created_at: resolution.created_at.iso8601(3),
reason: 'Test reason for resolution'
})
end
end

context 'when resolution is a decision with creator_id' do
let(:resolution) do
create(:power_of_attorney_request_resolution, :with_decision)
end

before { request.update(resolution: resolution) }

it 'includes resolution details with type decision and creator_id' do
expect(subject[:resolution]).to eq({
id: resolution.id,
type: 'power_of_attorney_request_decision',
created_at: resolution.created_at.iso8601(3),
reason: 'Test reason for resolution',
creator_id: resolution.resolving.creator_id
})
end
end

context 'when resolution is a declination with reason' do
let(:resolution) do
create(:power_of_attorney_request_resolution, :with_declination,
reason: "Didn't authorize treatment record disclosure")
end

before { request.update(resolution: resolution) }

it 'includes resolution details with type decision, reason, and creator_id' do
expect(subject[:resolution]).to eq({
id: resolution.id,
type: 'power_of_attorney_request_decision',
created_at: resolution.created_at.iso8601(3),
reason: "Didn't authorize treatment record disclosure",
creator_id: resolution.resolving.creator_id
})
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

0 comments on commit c6e4481

Please sign in to comment.