diff --git a/CHANGELOG.md b/CHANGELOG.md index 43311e7..711fbd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [unreleased] -- See diff: https://github.com/barkibu/kb-ruby/compare/v0.25...HEAD +- See diff: https://github.com/barkibu/kb-ruby/compare/v0.26...HEAD + +# [0.26.0] +- Add `#iban` and `#update_iban` to `PetParent` +- Add /iban endpoints in fake API # [0.25.0] - Add support for Ruby 3.2 diff --git a/Gemfile.lock b/Gemfile.lock index 7878197..e7c21c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - barkibu-kb (0.25.0) + barkibu-kb (0.26.0) activemodel (>= 4.0.2) activerecord activesupport (>= 3.0.0) @@ -10,8 +10,8 @@ PATH faraday-http faraday_middleware i18n - barkibu-kb-fake (0.25.0) - barkibu-kb (= 0.25.0) + barkibu-kb-fake (0.26.0) + barkibu-kb (= 0.26.0) countries sinatra webmock diff --git a/README.md b/README.md index 113a5ff..739c969 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,11 @@ KB.config.log_level = :debugger # :info by default - returns all the KB::Referral associated with this pet parent - `referrers` - returns all the KB::Referral associated with any of the pet parent's pets +- `iban` + - returns the IBAN of the pet parent +- `update_iban` + - arg: `iban` string + - updates the IBAN of the pet parent and reloads the entity #### Assessment 📄 diff --git a/lib/kb/fake/bounded_context/pet_family/pet_parents.rb b/lib/kb/fake/bounded_context/pet_family/pet_parents.rb index 2b10f0f..944480d 100644 --- a/lib/kb/fake/bounded_context/pet_family/pet_parents.rb +++ b/lib/kb/fake/bounded_context/pet_family/pet_parents.rb @@ -15,6 +15,15 @@ def petparents_filterable_attributes KB::PetParent::FIELDS.map { |k| k.to_s.camelize(:lower) } end + def on_petparents_show(_version) + pet_parent = pet_parent_by_key(params).dup + return json_response 404, {} if pet_parent.nil? + + pet_parent['iban_last4'] = pet_parent.delete('iban')&.chars&.last(4)&.join + + json_response 200, pet_parent + end + get '/v1/petparents/:key/pets' do json_response 200, pets_by_pet_parent_key(params['key']) end @@ -70,6 +79,25 @@ def petparents_filterable_attributes json_response 200, resource end + get '/v1/petparents/:key/iban' do + pet_parent = pet_parent_by_key(params) + return json_response 404, {} if pet_parent.blank? + + json_response 200, { iban: pet_parent['iban'] } + end + + put '/v1/petparents/:key/iban' do + pet_parent = pet_parent_by_key(params) + return json_response 404, {} if pet_parent.blank? + + body = JSON.parse(request.body.read) + + updated_pet_parent = pet_parent.merge body.slice('iban') + update_resource_state(:petparents, updated_pet_parent) + + json_response 200, { iban: updated_pet_parent['iban'] } + end + private def pet_parent_by_key(params) diff --git a/lib/kb/models/assessment.rb b/lib/kb/models/assessment.rb index 6fc86bc..5daa030 100644 --- a/lib/kb/models/assessment.rb +++ b/lib/kb/models/assessment.rb @@ -30,6 +30,9 @@ def attributes_from_response(response) end end + STRING_FIELDS = %i[key pet_key urgency].freeze + FIELDS = [*STRING_FIELDS, :date, :should_stop, :finished, :conditions, :symptoms, :next_question].freeze + # Legacy Field Name From Anamnesis alias_attribute :consultation_id, :key alias_attribute :should_stop, :finished @@ -42,12 +45,7 @@ def attributes_from_response(response) attribute :date, :datetime attribute :finished, :boolean, default: false - attribute :urgency, :string - attribute :key, :string - attribute :pet_key, :string - - STRING_FIELDS = %i[key pet_key urgency].freeze - FIELDS = [*STRING_FIELDS, :date, :should_stop, :finished, :conditions, :symptoms, :next_question].freeze + define_attributes STRING_FIELDS, :string def urgent return false if urgency == 'low' diff --git a/lib/kb/models/base_model.rb b/lib/kb/models/base_model.rb index 0b49985..51a3dfc 100644 --- a/lib/kb/models/base_model.rb +++ b/lib/kb/models/base_model.rb @@ -13,6 +13,23 @@ class BaseModel class << self delegate :clear_cache_for, to: :kb_client + + def define_attribute_methods(*fields) + super + fields.each do |field| + define_method :"#{field}=" do |value| + super(value).tap do + public_send "#{field}_will_change!" if public_send("#{field}_changed?") + end + end + end + end + + def define_attributes(attributes, cast_type = nil) + attributes.each do |attribute| + attribute attribute, cast_type&.to_sym + end + end end def initialize(attributes = {}) @@ -39,16 +56,5 @@ def ==(other) other.key == key) end alias eql? == - - def self.define_attribute_methods(*fields) - super - fields.each do |field| - define_method :"#{field}=" do |value| - super(value).tap do - public_send "#{field}_will_change!" if public_send("#{field}_changed?") - end - end - end - end end end diff --git a/lib/kb/models/breed.rb b/lib/kb/models/breed.rb index 9ea10d2..5af7051 100644 --- a/lib/kb/models/breed.rb +++ b/lib/kb/models/breed.rb @@ -32,8 +32,6 @@ def self.attributes_from_response(response) define_attribute_methods(*FIELDS) - STRING_FIELDS.each do |field| - attribute field, :string - end + define_attributes STRING_FIELDS, :string end end diff --git a/lib/kb/models/concerns/findable.rb b/lib/kb/models/concerns/findable.rb index 37c5ca6..ee55ac0 100644 --- a/lib/kb/models/concerns/findable.rb +++ b/lib/kb/models/concerns/findable.rb @@ -15,5 +15,11 @@ def find(key, params = {}) raise KB::Error.from_faraday(e) end end + + def reload + self.class.clear_cache_for(key) + self.attributes = self.class.find(key).attributes + self + end end end diff --git a/lib/kb/models/hubspot_relationship.rb b/lib/kb/models/hubspot_relationship.rb index 33bb006..48e52a1 100644 --- a/lib/kb/models/hubspot_relationship.rb +++ b/lib/kb/models/hubspot_relationship.rb @@ -16,13 +16,8 @@ def self.attributes_from_response(response) define_attribute_methods(*FIELDS) - STRING_FIELDS.each do |field| - attribute field, :string - end - - DATE_FIELDS.each do |field| - attribute field, :date - end + define_attributes STRING_FIELDS, :string + define_attributes DATE_FIELDS, :date def self.find(model, model_key) response = kb_client.request("#{model}/#{model_key}/relationship") diff --git a/lib/kb/models/pet.rb b/lib/kb/models/pet.rb index 13556ee..cdf5e82 100644 --- a/lib/kb/models/pet.rb +++ b/lib/kb/models/pet.rb @@ -21,17 +21,9 @@ def self.attributes_from_response(response) define_attribute_methods(*FIELDS) - STRING_FIELDS.each do |field| - attribute field, :string - end - - BOOLEAN_FIELDS.each do |field| - attribute field, :boolean - end - - DATE_FIELDS.each do |field| - attribute field, :date - end + define_attributes STRING_FIELDS, :string + define_attributes DATE_FIELDS, :date + define_attributes BOOLEAN_FIELDS, :boolean def save! return unless changed? diff --git a/lib/kb/models/pet_contract.rb b/lib/kb/models/pet_contract.rb index 62e80f4..d42ba1d 100644 --- a/lib/kb/models/pet_contract.rb +++ b/lib/kb/models/pet_contract.rb @@ -31,17 +31,9 @@ def self.attributes_from_response(response) define_attribute_methods(*FIELDS) - STRING_FIELDS.each do |field| - attribute field, :string - end - - DATE_FIELDS.each do |field| - attribute field, :date - end - - INTEGER_FIELDS.each do |field| - attribute field, :integer - end + define_attributes STRING_FIELDS, :string + define_attributes DATE_FIELDS, :date + define_attributes INTEGER_FIELDS, :integer def save! return unless changed? diff --git a/lib/kb/models/pet_parent.rb b/lib/kb/models/pet_parent.rb index 9656818..d064617 100644 --- a/lib/kb/models/pet_parent.rb +++ b/lib/kb/models/pet_parent.rb @@ -41,8 +41,8 @@ def self.attributes_from_response(response) private_class_method :attributes_from_response - STRING_FIELDS = %i[key partner_name first_name last_name prefix_phone_number - phone_number email country address zip_code nif affiliate_code city].freeze + STRING_FIELDS = %i[key partner_name first_name last_name prefix_phone_number phone_number email country address + zip_code nif affiliate_code city iban_last4].freeze DATE_FIELDS = %i[birth_date deleted_at].freeze BOOLEAN_FIELDS = %i[phone_number_verified email_verified].freeze FIELDS = [*STRING_FIELDS, *DATE_FIELDS, *BOOLEAN_FIELDS].freeze @@ -52,18 +52,9 @@ def self.attributes_from_response(response) alias phone_number_prefix prefix_phone_number alias phone_number_prefix= prefix_phone_number= - STRING_FIELDS.each do |field| - attribute field, :string - end - - DATE_FIELDS.each do |field| - attribute field, :date - end - - BOOLEAN_FIELDS.each do |field| - attribute field, :boolean - end - + define_attributes STRING_FIELDS, :string + define_attributes DATE_FIELDS, :date + define_attributes BOOLEAN_FIELDS, :boolean attribute :first_name, :string, default: '' def save! @@ -119,5 +110,18 @@ def referrers Referral.from_api(referral) end end + + def iban + @iban ||= self.class.kb_client.request("#{key}/iban")['iban'] + rescue Faraday::Error => e + raise KB::Error.from_faraday(e) + end + + def update_iban(iban) + self.class.kb_client.request("#{key}/iban", filters: { iban: iban }, method: :put) + reload + rescue Faraday::Error => e + raise KB::Error.from_faraday(e) + end end end diff --git a/lib/kb/models/plan.rb b/lib/kb/models/plan.rb index 451f20d..301ae8c 100644 --- a/lib/kb/models/plan.rb +++ b/lib/kb/models/plan.rb @@ -19,13 +19,8 @@ def self.attributes_from_response(response) attribute :plan_life_in_months, :integer attribute :buyable, :boolean - STRING_FIELDS.each do |field| - attribute field, :string - end - - HASH_FIELDS.each do |field| - attribute field - end + define_attributes STRING_FIELDS, :string + define_attributes HASH_FIELDS def save! return unless changed? diff --git a/lib/kb/models/product.rb b/lib/kb/models/product.rb index 2c600d6..33a5b06 100644 --- a/lib/kb/models/product.rb +++ b/lib/kb/models/product.rb @@ -23,12 +23,7 @@ def self.attributes_from_response(response) attribute :purchasable, :boolean - STRING_FIELDS.each do |field| - attribute field, :string - end - - STRING_ARRAY_FIELDS.each do |field| - attribute field, :array_of_strings - end + define_attributes STRING_FIELDS, :string + define_attributes STRING_ARRAY_FIELDS, :array_of_strings end end diff --git a/lib/kb/models/referral.rb b/lib/kb/models/referral.rb index 75ab36c..cd97d34 100644 --- a/lib/kb/models/referral.rb +++ b/lib/kb/models/referral.rb @@ -16,13 +16,8 @@ def self.attributes_from_response(response) define_attribute_methods(*FIELDS) - STRING_FIELDS.each do |field| - attribute field, :string - end - - DATE_FIELDS.each do |field| - attribute field, :date - end + define_attributes STRING_FIELDS, :string + define_attributes DATE_FIELDS, :date def self.create(pet_parent_key, attributes) response = kb_client.request("#{pet_parent_key}/referrals", filters: attributes, method: :post) diff --git a/lib/kb/version.rb b/lib/kb/version.rb index d35ba1a..ecb67ad 100644 --- a/lib/kb/version.rb +++ b/lib/kb/version.rb @@ -1,3 +1,3 @@ module KB - VERSION = '0.25.0'.freeze + VERSION = '0.26.0'.freeze end diff --git a/spec/fake/models/pet_parent_spec.rb b/spec/fake/models/pet_parent_spec.rb index d32fe88..ba90b53 100644 --- a/spec/fake/models/pet_parent_spec.rb +++ b/spec/fake/models/pet_parent_spec.rb @@ -168,4 +168,48 @@ end end end + + describe '#iban_last4' do + context 'with an existing pet parent' do + let(:pet_parent) { described_class.new described_class.create } + + context 'with no iban' do + it 'returns nil' do + expect(pet_parent.iban_last4).to be_nil + end + end + + context 'with an iban' do + before do + pet_parent.update_iban('ES9121000418450200051332') + end + + it 'returns the last 4 digits from the iban of the pet parent' do + expect(pet_parent.iban_last4).to eq('1332') + end + end + end + end + + describe '#iban' do + context 'with an existing pet parent' do + let(:pet_parent) { described_class.new described_class.create } + + context 'with no iban' do + it 'returns nil' do + expect(pet_parent.iban).to be_nil + end + end + + context 'with an iban' do + before do + pet_parent.update_iban('ES9121000418450200051332') + end + + it 'returns the iban of the pet parent' do + expect(pet_parent.iban).to eq('ES9121000418450200051332') + end + end + end + end end diff --git a/spec/models/pet_parent_spec.rb b/spec/models/pet_parent_spec.rb index 6821dd1..7ae6dc5 100644 --- a/spec/models/pet_parent_spec.rb +++ b/spec/models/pet_parent_spec.rb @@ -3,12 +3,12 @@ RSpec.describe KB::PetParent do let(:base_url) { 'https://test_api_barkkb.com/v1' } + let(:pet_parent) { described_class.new(key: pet_parent_key) } + let(:pet_parent_key) { 'pet_parent_key' } + describe '#referrals' do subject(:referrals) { pet_parent.referrals } - let(:pet_parent) { described_class.new(key: pet_parent_key) } - let(:pet_parent_key) { 'pet_parent_key' } - context 'when no referrals exist for pet parent' do before do stub_request(:get, "#{base_url}/petparents/#{pet_parent_key}/referrals") @@ -76,8 +76,6 @@ describe '#referrers' do subject(:referrers) { pet_parent.referrers } - let(:pet_parent) { described_class.new(key: pet_parent_key) } - let(:pet_parent_key) { 'pet_parent_key' } let(:referrer_pet_parent_key) { 'referrer_pet_parent_key' } context 'when no referrers exist for pet parent' do @@ -143,4 +141,45 @@ end end end + + describe '#iban' do + subject(:iban) { pet_parent.iban } + + before do + stub_request(:get, "#{base_url}/petparents/#{pet_parent_key}/iban") + .to_return(status: 200, body: { iban: 'DE89370400440532013000' }.to_json) + end + + it 'GETs the iban from the endpoint' do + iban + expect(a_request(:get, "#{base_url}/petparents/#{pet_parent_key}/iban")).to have_been_made + end + end + + describe '#update_iban' do + subject(:update_iban) { pet_parent.update_iban(new_iban) } + + let(:new_iban) { 'DE89370400440532013000' } + + before do + stub_request(:put, "#{base_url}/petparents/#{pet_parent_key}/iban") + .to_return(status: 200, body: { iban: new_iban }.to_json) + + stub_request(:get, "#{base_url}/petparents/#{pet_parent_key}") + .to_return(status: 200, body: pet_parent.attributes.to_json) + + allow(pet_parent).to receive(:reload).and_call_original + end + + it 'PUTs the iban in the endpoint' do + update_iban + expect(a_request(:put, "#{base_url}/petparents/#{pet_parent_key}/iban").with(body: { iban: new_iban }.to_json)) + .to have_been_made + end + + it 'reloads the pet parent' do + update_iban + expect(pet_parent).to have_received(:reload) + end + end end