Skip to content

Commit

Permalink
Update beneficiary address rules
Browse files Browse the repository at this point in the history
  • Loading branch information
samnang committed Jan 9, 2025
1 parent 04977fc commit 7fac5b3
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 23 deletions.
5 changes: 0 additions & 5 deletions app/request_schemas/schema_rules/beneficiary_address_rules.rb

This file was deleted.

22 changes: 5 additions & 17 deletions app/request_schemas/v1/beneficiary_address_request_schema.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module V1
class BeneficiaryAddressRequestSchema < JSONAPIRequestSchema
option :beneficiary_address_rules, default -> { BeneficiaryAddressRules.new }

params do
required(:data).value(:hash).schema do
required(:type).filled(:str?, eql?: "address")
Expand All @@ -17,23 +15,13 @@ class BeneficiaryAddressRequestSchema < JSONAPIRequestSchema
end
end
end
end

attribute_rule do |attributes|
(4..3).each do |level|
division_attributes = [:code, :name].map { |type| :"administrative_division_level_#{level}_#{type}" }

next if division_attributes.all? { |division_attribute| attributes[division_attribute].blank? }

(3..2).each do |parent_level|
next if level == parent_level

parent_division_attributes = [:code, :name].map { |type| :"administrative_division_level_#{parent_level}_#{type}" }

next if parent_division_attributes.any? { |parent_division_attribute| attributes[parent_division_attribute].present? }
attribute_rule do |attributes|
validator = BeneficiaryAddressValidator.new(attributes)
next if validator.valid?

key([:data, :attributes, parent_division_attributes.first]).failure("must be present")
break
validator.errors.each do |error|
key([ :data, :attributes, error.key ]).failure(text: error.message)
end
end
end
Expand Down
13 changes: 12 additions & 1 deletion app/request_schemas/v1/beneficiary_request_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,18 @@ class BeneficiaryRequestSchema < JSONAPIRequestSchema
attribute_rule(:phone_number) do |attributes|
next unless account.contacts.where_msisdn(attributes.fetch(:phone_number)).exists?

key([:data, :attributes, :phone_number]).failure(text: "must be unique")
key([ :data, :attributes, :phone_number ]).failure(text: "must be unique")
end

attribute_rule(:address) do |attributes|
next if attributes[:address].blank?

validator = BeneficiaryAddressValidator.new(attributes[:address])
next if validator.valid?

validator.errors.each do |error|
key([ :data, :attributes, :address, error.key ]).failure(text: error.message)
end
end

def output
Expand Down
29 changes: 29 additions & 0 deletions app/validators/beneficiary_address_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class BeneficiaryAddressValidator
attr_reader :attributes, :errors

Error = Data.define(:key, :message)

def initialize(attributes)
@attributes = attributes
@errors = []
end


def valid?
4.downto(3) do |level|
division_attributes = [ :code, :name ].map { |type| :"administrative_division_level_#{level}_#{type}" }

next if division_attributes.all? { |division_attribute| attributes[division_attribute].blank? }

parent_level = level - 1
parent_division_attributes = [ :code, :name ].map { |type| :"administrative_division_level_#{parent_level}_#{type}" }

next if parent_division_attributes.any? { |parent_division_attribute| attributes[parent_division_attribute].present? }

errors << Error.new(key: parent_division_attributes.first, message: "must be present")
return false
end

errors.empty?
end
end
22 changes: 22 additions & 0 deletions spec/request_schemas/v1/beneficiary_address_request_schema_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require "rails_helper"

module V1
RSpec.describe BeneficiaryAddressRequestSchema, type: :request_schema do
it "validates the address" do
expect(
validate_schema(input_params: { data: { attributes: { iso_country_code: "KH", iso_region_code: "KH-1", administrative_division_level_2_code: "0101", administrative_division_level_3_code: "010101" } } })
).to have_valid_field(:data, :attributes, :administrative_division_level_2_code)

expect(
validate_schema(input_params: { data: { attributes: { iso_country_code: "KH", iso_region_code: "KH-1", administrative_division_level_3_code: "010101" } } })
).not_to have_valid_field(:data, :attributes, :administrative_division_level_2_code)
end

def validate_schema(input_params:, options: {})
BeneficiaryAddressRequestSchema.new(
input_params:,
options:
)
end
end
end
8 changes: 8 additions & 0 deletions spec/request_schemas/v1/beneficiary_request_schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ module V1
expect(
validate_schema(input_params: { data: { attributes: { address: { iso_region_code: "KH-1" } } } })
).to have_valid_field(:data, :attributes, :address, :iso_region_code)

expect(
validate_schema(input_params: { data: { attributes: { address: { iso_country_code: "KH", iso_region_code: "KH-1", administrative_division_level_2_code: "0101", administrative_division_level_3_code: "010101" } } } })
).to have_valid_field(:data, :attributes, :address, :administrative_division_level_2_code)

expect(
validate_schema(input_params: { data: { attributes: { address: { iso_country_code: "KH", iso_region_code: "KH-1", administrative_division_level_3_code: "010101" } } } })
).not_to have_valid_field(:data, :attributes, :address, :administrative_division_level_2_code)
end

it "validates the metadata fields attributes" do
Expand Down

0 comments on commit 7fac5b3

Please sign in to comment.