Skip to content
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

Beneficiary's Addresses API #1676

Merged
merged 2 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions app/controllers/api/v1/addresses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module API
module V1
class AddressesController < BaseController
def index
respond_with_resource(beneficiary.addresses)
end

def create
validate_request_schema(
with: ::V1::BeneficiaryAddressRequestSchema,
location: ->(resource) { api_v1_beneficiary_address_path(beneficiary, resource) }
) do |permitted_params|
beneficiary.addresses.create!(permitted_params)
end
end

def show
address = beneficiary.addresses.find(params[:id])
respond_with_resource(address)
end

def destroy
address = beneficiary.addresses.find(params[:id])
address.destroy!

head :no_content
end

def beneficiary
@beneficiary ||= current_account.beneficiaries.find(params[:beneficiary_id])
end
end
end
end
6 changes: 4 additions & 2 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Account < ApplicationRecord
DEFAULT_PERMISSIONS_BITMASK = 0
TWILIO_ACCOUNT_SID_PREFIX = "AC".freeze
DEFAULT_PLATFORM_PROVIDER = "twilio".freeze
PLATFORM_PROVIDERS = [DEFAULT_PLATFORM_PROVIDER, "somleng"].freeze
PLATFORM_PROVIDERS = [ DEFAULT_PLATFORM_PROVIDER, "somleng" ].freeze
DEFAULT_CALL_FLOW_LOGIC = "CallFlowLogic::HelloWorld".freeze

include MetadataHelpers
Expand All @@ -27,6 +27,8 @@ class Account < ApplicationRecord

has_many :contacts,
dependent: :restrict_with_error
has_many :beneficiaries, class_name: "Contact",
dependent: :restrict_with_error

has_many :callouts,
dependent: :restrict_with_error
Expand Down Expand Up @@ -93,7 +95,7 @@ def write_batch_operation_access_token
end

def phone_call_queue_limit
[settings.fetch("phone_call_queue_limit").to_i, 1000].max
[ settings.fetch("phone_call_queue_limit").to_i, 1000 ].max
end

def from_phone_number
Expand Down
22 changes: 22 additions & 0 deletions app/request_schemas/v1/beneficiary_address_request_schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module V1
class BeneficiaryAddressRequestSchema < BaseRequestSchema
params do
required(:data).value(:hash).schema do
required(:type).filled(:str?, eql?: "address")
required(:attributes).value(:hash).schema do
required(:iso_region_code).maybe(:string)
optional(:administrative_division_level_2_code).maybe(:string)
optional(:administrative_division_level_2_name).maybe(:string)
optional(:administrative_division_level_3_code).maybe(:string)
optional(:administrative_division_level_3_name).maybe(:string)
optional(:administrative_division_level_4_code).maybe(:string)
optional(:administrative_division_level_4_name).maybe(:string)
end
end
end

def output
super.except(:account)
end
end
end
2 changes: 1 addition & 1 deletion app/request_schemas/v1/beneficiary_request_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class BeneficiaryRequestSchema < BaseRequestSchema
optional(:metadata).value(:hash)

optional(:address).filled(:hash).schema do
optional(:iso_region_code).maybe(:string)
required(:iso_region_code).maybe(:string)
optional(:administrative_division_level_2_code).maybe(:string)
optional(:administrative_division_level_2_name).maybe(:string)
optional(:administrative_division_level_3_code).maybe(:string)
Expand Down
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@
end

namespace :v1, module: "api/v1", as: "api_v1", defaults: { format: "json" } do
resources :beneficiaries, only: [ :index, :create, :show, :update ]
resources :beneficiaries, only: [ :index, :create, :show, :update ] do
resources :addresses, only: [ :index, :create, :show, :destroy ]
end
end

namespace "api", defaults: { format: "json" } do
Expand Down
5 changes: 5 additions & 0 deletions spec/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,9 @@

association :audio_file, factory: :active_storage_attachment, filename: "test.mp3"
end

factory :address, class: "BeneficiaryAddress" do
beneficiary
iso_region_code { "KH-1" }
end
end
84 changes: 84 additions & 0 deletions spec/requests/open_ews_api/v1/beneficiaries/addresses_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require "rails_helper"

RSpec.resource "Beneficiary's Addresses" do
get "/v1/beneficiaries/:beneficiary_id/addresses" do
example "List all a beneficiary's addresses" do
account = create(:account)
beneficiary = create(:beneficiary, account:)
address1 = create(:address, beneficiary:)
address2 = create(:address, beneficiary:)
other_beneficiary = create(:beneficiary)
_other_address = create(:address, beneficiary: other_beneficiary)

set_authorization_header_for(account)
do_request(beneficiary_id: beneficiary.id)

expect(response_status).to eq(200)
expect(response_body).to match_jsonapi_resource_collection_schema("address")
expect(json_response.fetch("data").pluck("id")).to contain_exactly(
address1.id.to_s,
address2.id.to_s
)
end
end

post "/v1/beneficiaries/:beneficiary_id/addresses" do
example "Create an address for a beneficiary" do
account = create(:account)
beneficiary = create(:beneficiary, account:)

set_authorization_header_for(account)
do_request(
beneficiary_id: beneficiary.id,
data: {
type: :address,
attributes: {
iso_region_code: "KH-1",
administrative_division_level_2_code: "01"
}
}
)

expect(response_status).to eq(201)
expect(response_body).to match_jsonapi_resource_schema("address")
expect(jsonapi_response_attributes).to include(
"iso_region_code" => "KH-1",
"administrative_division_level_2_code" => "01"
)
end
end

get "/v1/beneficiaries/:beneficiary_id/addresses/:id" do
example "Get an address for a beneficiary" do
account = create(:account)
beneficiary = create(:beneficiary, account:)
address = create(:address, beneficiary:)

set_authorization_header_for(account)
do_request(
beneficiary_id: beneficiary.id,
id: address.id
)

expect(response_status).to eq(200)
expect(response_body).to match_jsonapi_resource_schema("address")
expect(json_response.dig("data", "id")).to eq(address.id.to_s)
end
end

delete "/v1/beneficiaries/:beneficiary_id/addresses/:id" do
example "Delete an address for a beneficiary" do
account = create(:account)
beneficiary = create(:beneficiary, account:)
address = create(:address, beneficiary:)

set_authorization_header_for(account)
do_request(
beneficiary_id: beneficiary.id,
id: address.id
)

expect(response_status).to eq(204)
end
end
end
64 changes: 64 additions & 0 deletions spec/requests/open_ews_api/v1/beneficiaries_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

RSpec.resource "Beneficiaries" do
get "/v1/beneficiaries" do
with_options scope: :filter do
parameter(
:status, "Must be one of #{Contact.status.values.map { |t| "`#{t}`" }.join(", ")}.",
required: false
)
end

example "List all active beneficiaries" do
account = create(:account)
account_beneficiary = create(:beneficiary, account:)
Expand Down Expand Up @@ -35,6 +42,63 @@
end

post "/v1/beneficiaries" do
with_options scope: %i[data attributes] do
parameter(
:msisdn, "Phone number in E.164 format or shortcode.",
required: true
)
parameter(
:language_code, "Language code in ISO 639-1 format.",
required: false
)
parameter(
:gender, "Must be one of `M` or `F`.",
required: false
)
parameter(
:date_of_birth, "Date of birth in `YYYY-MM-DD` format.",
required: false
)
parameter(
:iso_country_code, "The ISO 3166-1 alpha-2 country code of the phone number. It must be matched with the country of `msisdn` parameter.",
required: false
)
parameter(
:metadata, "Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.",
required: false
)
with_options scope: :address do
parameter(
:iso_region_code, "ISO 3166-2 of the country's subdivisions(e.g., provinces or states)",
required: false
)
parameter(
:administrative_division_level_2_code, "Code of administrative division level 2(e.g. district)",
required: false
)
parameter(
:administrative_division_level_2_name, "Name of administrative division level 2",
required: false
)
parameter(
:administrative_division_level_3_code, "Code of administrative division level 2(e.g. commune)",
required: false
)
parameter(
:administrative_division_level_3_name, "Name of administrative division level 3",
required: false
)
parameter(
:administrative_division_level_4_code, "Code of administrative division level 4(e.g. village)",
required: false
)
parameter(
:administrative_division_level_4_name, "Name of administrative division level 4",
required: false
)
end
end

example "Create a beneficiary" do
account = create(:account)

Expand Down
Loading