From 2655da4555910baa2afd2ecfa22d06a617262677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andres=20Keskk=C3=BCla?= Date: Mon, 25 Aug 2014 17:05:57 +0300 Subject: [PATCH] Replaced address with local and international addr --- app/controllers/concerns/epp/common.rb | 9 ++++ app/helpers/epp/contacts_helper.rb | 24 +++++++--- app/models/address.rb | 45 +++++++++++++++---- app/models/contact.rb | 23 ++++++---- app/models/international_address.rb | 3 ++ app/models/local_address.rb | 3 ++ .../epp/contacts/_postal_info.xml.builder | 27 +++++++++++ app/views/epp/contacts/info.xml.builder | 10 +---- ...140822122938_add_postal_info_to_address.rb | 10 +++++ db/schema.rb | 7 +-- spec/epp/contact_spec.rb | 33 ++++++++++---- .../contacts/create_with_two_addresses.xml | 45 +++++++++++++++++++ spec/fabricators/contact_fabricator.rb | 3 +- ...rb => international_address_fabricator.rb} | 3 +- spec/models/address_spec.rb | 13 +++--- spec/models/contact_spec.rb | 7 ++- 16 files changed, 208 insertions(+), 57 deletions(-) create mode 100644 app/models/international_address.rb create mode 100644 app/models/local_address.rb create mode 100644 app/views/epp/contacts/_postal_info.xml.builder create mode 100644 db/migrate/20140822122938_add_postal_info_to_address.rb create mode 100644 spec/epp/requests/contacts/create_with_two_addresses.xml rename spec/fabricators/{address_fabricator.rb => international_address_fabricator.rb} (67%) diff --git a/app/controllers/concerns/epp/common.rb b/app/controllers/concerns/epp/common.rb index 23b9d0f3c..5c4f21d7a 100644 --- a/app/controllers/concerns/epp/common.rb +++ b/app/controllers/concerns/epp/common.rb @@ -57,6 +57,15 @@ module Epp::Common epp_errors.empty? end + def xml_nested_attrs_present?(array_ph, attributes ) + [array_ph].flatten.each do |ph| + attributes.each do |x| + epp_errors << {code: '2003', msg: I18n.t('errors.messages.required_parameter_missing', key: x.last)} unless has_attribute(ph, x) + end + end + epp_errors.empty? + end + def has_attribute(ph, path) path.inject(ph) do |location, key| location.respond_to?(:keys) ? location[key] : nil diff --git a/app/helpers/epp/contacts_helper.rb b/app/helpers/epp/contacts_helper.rb index 0ec5baeed..0beccb273 100644 --- a/app/helpers/epp/contacts_helper.rb +++ b/app/helpers/epp/contacts_helper.rb @@ -48,9 +48,14 @@ module Epp::ContactsHelper @ph = params_hash['epp']['command']['create']['create'] xml_attrs_present?(@ph, [['id'], ['authInfo', 'pw'], - ['postalInfo', 'name'], - ['postalInfo', 'addr', 'city'], - ['postalInfo', 'addr', 'cc']]) + ['postalInfo']]) +# ['postalInfo', 'addr', 'city'], +# ['postalInfo', 'addr', 'cc']]) + if @ph['postalInfo'].is_a?(Hash) || @ph['postalInfo'].is_a?(Array) + xml_nested_attrs_present?( @ph['postalInfo'], [['name'], + ['addr', 'city'], + ['addr', 'cc']] ) + end end ## UPDATE @@ -101,12 +106,17 @@ module Epp::ContactsHelper case type when :update contact_hash = Contact.extract_attributes(@ph[:chg], type) - contact_hash[:address_attributes] = - Address.extract_attributes(( @ph.try(:[], :chg).try(:[], :postalInfo).try(:[], :addr) || [] ), type) + #contact_hash[:address_attributes] = + contact_hash = contact_hash.merge( + Address.extract_attributes(( @ph.try(:[], :chg).try(:[], :postalInfo) || [] ), type) + ) else contact_hash = Contact.extract_attributes(@ph, type) - contact_hash[:address_attributes] = - Address.extract_attributes(( @ph.try(:[], :postalInfo).try(:[], :addr) || [] ), type) + #contact_hash[:address_attributes] = + # Address.extract_attributes(( @ph.try(:[], :postalInfo) || [] ), type) + contact_hash = contact_hash.merge( + Address.extract_attributes(( @ph.try(:[], :postalInfo) || [] ), type) + ) end contact_hash[:ident_type] = ident_type unless ident_type.nil? contact_hash diff --git a/app/models/address.rb b/app/models/address.rb index 3ddad202d..60524cff0 100644 --- a/app/models/address.rb +++ b/app/models/address.rb @@ -1,20 +1,47 @@ class Address < ActiveRecord::Base + LOCAL_TYPE_SHORT = 'loc' + INTERNATIONAL_TYPE_SHORT = 'int' + LOCAL_TYPE = 'LocalAddress' + TYPES = [ + LOCAL_TYPE_SHORT, + INTERNATIONAL_TYPE_SHORT + ] + belongs_to :contact belongs_to :country + #validates_inclusion_of :type, in: TYPES + class << self def extract_attributes ah, type=:create address_hash = {} - address_hash = ({ - country_id: Country.find_by(iso: ah[:cc]).try(:id), - city: ah[:city], - street: ah[:street][0], - street2: ah[:street][1], - street3: ah[:street][2], - zip: ah[:pc] - }) if ah.is_a?(Hash) - address_hash.delete_if { |k, v| v.nil? } + [ah].flatten.each do |pi| + address_hash[local?(pi)] = addr_hash_from_params(pi) + end + + address_hash + end + + private + + def local?(postal_info) + return :local_address_attributes if postal_info[:type] == LOCAL_TYPE_SHORT + :international_address_attributes + end + + def addr_hash_from_params(addr) + return {} unless addr[:addr].is_a?(Hash) + { + name: addr[:name], + org_name: addr[:org], + country_id: Country.find_by(iso: addr[:addr][:cc]).try(:id), + city: addr[:addr][:city], + street: addr[:addr][:street][0], + street2: addr[:addr][:street][1], + street3: addr[:addr][:street][2], + zip: addr[:addr][:pc] + }.delete_if { |k, v| v.nil? } end end end diff --git a/app/models/contact.rb b/app/models/contact.rb index 9d554ecf0..6a3cbc44c 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -6,16 +6,18 @@ class Contact < ActiveRecord::Base EPP_ATTR_MAP = {} - has_one :address + has_one :local_address#, class_name: 'Address'#, foreign_key: 'local_address_id' + has_one :international_address + has_many :domain_contacts has_many :domains, through: :domain_contacts belongs_to :created_by, class_name: 'EppUser', foreign_key: :created_by_id belongs_to :updated_by, class_name: 'EppUser', foreign_key: :updated_by_id - accepts_nested_attributes_for :address + accepts_nested_attributes_for :local_address, :international_address - validates_presence_of :code, :name, :phone, :email, :ident + validates_presence_of :code, :phone, :email, :ident validate :ident_must_be_valid @@ -36,6 +38,16 @@ class Contact < ActiveRecord::Base CONTACT_TYPE_ADMIN = 'admin' CONTACT_TYPES = [CONTACT_TYPE_TECH, CONTACT_TYPE_ADMIN] + #TEMP METHODS for transaction to STI + def name + international_address.name + end + + def address + international_address + end + ## + def ident_must_be_valid #TODO Ident can also be passport number or company registry code. #so have to make changes to validations (and doc/schema) accordingly @@ -114,11 +126,6 @@ class Contact < ActiveRecord::Base email: ph[:email] } - contact_hash = contact_hash.merge({ - name: ph[:postalInfo][:name], - org_name: ph[:postalInfo][:org] - }) if ph[:postalInfo].is_a? Hash - contact_hash[:code] = ph[:id] if type == :create contact_hash.delete_if { |k, v| v.nil? } diff --git a/app/models/international_address.rb b/app/models/international_address.rb new file mode 100644 index 000000000..20a3cb27f --- /dev/null +++ b/app/models/international_address.rb @@ -0,0 +1,3 @@ +class InternationalAddress < Address + +end diff --git a/app/models/local_address.rb b/app/models/local_address.rb new file mode 100644 index 000000000..1f6fa93bb --- /dev/null +++ b/app/models/local_address.rb @@ -0,0 +1,3 @@ +class LocalAddress < Address + +end diff --git a/app/views/epp/contacts/_postal_info.xml.builder b/app/views/epp/contacts/_postal_info.xml.builder new file mode 100644 index 000000000..ffa165bb7 --- /dev/null +++ b/app/views/epp/contacts/_postal_info.xml.builder @@ -0,0 +1,27 @@ +if @contact.international_address + address = @contact.international_address + xml.tag!('contact:postalInfo', type: 'int') do # TODO instance method of defining type + xml.tag!('contact:name', address.name) + xml.tag!('contact:org', address.org_name) + xml.tag!('contact:addr') do + xml.tag!('contact:street', address.street) if address.street + xml.tag!('contact:street', address.street2) if address.street2 + xml.tag!('contact:street', address.street3) if address.street3 + xml.tag!('contact:cc', address.try(:country).try(:iso)) unless address.try(:country).nil? + end + end +end +if @contact.local_address + address = @contact.local_address + xml.tag!('contact:postalInfo', type: 'loc') do + xml.tag!('contact:name', address.name) + xml.tag!('contact:org', address.org_name) + xml.tag!('contact:addr') do + xml.tag!('contact:street', address.street) if address.street + xml.tag!('contact:street', address.street2) if address.street2 + xml.tag!('contact:street', address.street3) if address.street3 + xml.tag!('contact:cc', address.try(:country).try(:iso)) unless address.try(:country).nil? + end + end +end + diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder index e5a4a0fe8..576712ccc 100644 --- a/app/views/epp/contacts/info.xml.builder +++ b/app/views/epp/contacts/info.xml.builder @@ -6,15 +6,7 @@ xml.epp_head do xml.resData do xml.tag!('contact:chkData', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do - xml.tag!('contact:name', @contact.name) - xml.tag!('contact:org', @contact.org_name) - xml.tag!('contact:addr') do - address = @contact.address - xml.tag!('contact:street', address.street) if address.street - xml.tag!('contact:street', address.street2) if address.street2 - xml.tag!('contact:street', address.street3) if address.street3 - xml.tag!('contact:cc', address.try(:country).try(:iso)) unless address.try(:country).nil? - end + xml << render('/epp/contacts/postal_info') xml.tag!('contact:voice', @contact.phone) xml.tag!('contact:fax', @contact.fax) xml.tag!('contact:email', @contact.email) diff --git a/db/migrate/20140822122938_add_postal_info_to_address.rb b/db/migrate/20140822122938_add_postal_info_to_address.rb new file mode 100644 index 000000000..427eab48a --- /dev/null +++ b/db/migrate/20140822122938_add_postal_info_to_address.rb @@ -0,0 +1,10 @@ +class AddPostalInfoToAddress < ActiveRecord::Migration + def change + add_column :addresses, :name, :string + add_column :addresses, :org_name, :string + add_column :addresses, :type, :string + + remove_column :contacts, :name, :string + remove_column :contacts, :org_name, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 71d2b04e3..b7d4a4464 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140819103517) do +ActiveRecord::Schema.define(version: 20140822122938) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -26,11 +26,13 @@ ActiveRecord::Schema.define(version: 20140819103517) do t.datetime "updated_at" t.string "street2" t.string "street3" + t.string "name" + t.string "org_name" + t.string "type" end create_table "contacts", force: true do |t| t.string "code" - t.string "name" t.string "type" t.string "reg_no" t.string "phone" @@ -40,7 +42,6 @@ ActiveRecord::Schema.define(version: 20140819103517) do t.datetime "updated_at" t.string "ident" t.string "ident_type" - t.string "org_name" t.integer "created_by_id" t.integer "updated_by_id" t.string "auth_info" diff --git a/spec/epp/contact_spec.rb b/spec/epp/contact_spec.rb index bf3bb0dbb..884293531 100644 --- a/spec/epp/contact_spec.rb +++ b/spec/epp/contact_spec.rb @@ -29,17 +29,30 @@ describe 'EPP Contact', epp: true do expect(response[:result_code]).to eq('1000') expect(response[:msg]).to eq('Command completed successfully') expect(response[:clTRID]).to eq('ABC-12345') - expect(Contact.first.created_by_id).to be 1 - expect(Contact.first.updated_by_id).to be nil + expect(Contact.first.created_by_id).to eq 1 + expect(Contact.first.updated_by_id).to eq nil expect(Contact.count).to eq(1) - expect(Contact.first.org_name).to eq('Example Inc.') + + + expect(Contact.first.international_address.org_name).to eq('Example Inc.') expect(Contact.first.ident).to eq '37605030299' expect(Contact.first.ident_type).to eq 'op' - expect(Contact.first.address.street).to eq('123 Example Dr.') - expect(Contact.first.address.street2).to eq('Suite 100') - expect(Contact.first.address.street3).to eq nil + expect(Contact.first.international_address.street).to eq('123 Example Dr.') + expect(Contact.first.international_address.street2).to eq('Suite 100') + expect(Contact.first.international_address.street3).to eq nil + end + + it 'successfully creates contact with 2 addresses' do + response = epp_request('contacts/create_with_two_addresses.xml') + + expect(response[:result_code]).to eq('1000') + + expect(Contact.count).to eq(1) + expect(Contact.first.address).to_not eq Contact.first.local_address + expect(Address.count).to eq(2) + expect(LocalAddress.count).to eq(1) end it 'returns result data upon success' do @@ -62,6 +75,7 @@ describe 'EPP Contact', epp: true do response = epp_request(contact_create_xml, :xml) + expect(response[:result_code]).to eq('2302') expect(response[:msg]).to eq('Contact id already exists') @@ -207,8 +221,9 @@ describe 'EPP Contact', epp: true do end it 'returns info about contact' do - Fabricate(:contact, name: "Johnny Awesome", created_by_id: '1', code: 'info-4444', auth_info: '2fooBAR') - Fabricate(:address) + Fabricate(:contact, created_by_id: '1', code: 'info-4444', auth_info: '2fooBAR', + international_address: Fabricate(:international_address, name: 'Johnny Awesome')) + #Fabricate(:international_address, name: 'Johnny Awesome') response = epp_request('contacts/info.xml') contact = response[:parsed].css('resData chkData') @@ -220,7 +235,7 @@ describe 'EPP Contact', epp: true do end it 'doesn\'t display unassociated object' do - Fabricate(:contact, name:"Johnny Awesome", code: 'info-4444') + Fabricate(:contact, code: 'info-4444') response = epp_request('contacts/info.xml') expect(response[:result_code]).to eq('2201') diff --git a/spec/epp/requests/contacts/create_with_two_addresses.xml b/spec/epp/requests/contacts/create_with_two_addresses.xml new file mode 100644 index 000000000..f21d620d6 --- /dev/null +++ b/spec/epp/requests/contacts/create_with_two_addresses.xml @@ -0,0 +1,45 @@ + + + + + + loc_int + + John Doe Int + Example Int Inc. + + International street 1 + Dulles + VA + 20166-6503 + EE + + + + John Doe Loc + Example Loc Inc. + + Local street 1 + Vancouver + BC + 27123 + CA + + + +123.7035555555 + +1.7035555556 + jdoe@example.com + 37605030299 + + 2fooBAR + + + + + + + + ABC-12345 + + diff --git a/spec/fabricators/contact_fabricator.rb b/spec/fabricators/contact_fabricator.rb index 989bd2620..bcba61a4d 100644 --- a/spec/fabricators/contact_fabricator.rb +++ b/spec/fabricators/contact_fabricator.rb @@ -1,10 +1,9 @@ Fabricator(:contact) do - name Faker::Name.name phone '+372.12345678' email Faker::Internet.email ident '37605030299' code { "sh#{Faker::Number.number(4)}" } ident_type 'op' auth_info 'ccds4324pok' - address + international_address end diff --git a/spec/fabricators/address_fabricator.rb b/spec/fabricators/international_address_fabricator.rb similarity index 67% rename from spec/fabricators/address_fabricator.rb rename to spec/fabricators/international_address_fabricator.rb index 6018f18b2..02c902d76 100644 --- a/spec/fabricators/address_fabricator.rb +++ b/spec/fabricators/international_address_fabricator.rb @@ -1,4 +1,5 @@ -Fabricator(:address) do +Fabricator(:international_address) do + name Faker::Name.name city Faker::Address.city street Faker::Address.street_name street2 Faker::Address.street_name diff --git a/spec/models/address_spec.rb b/spec/models/address_spec.rb index 839f8a755..843e13b5c 100644 --- a/spec/models/address_spec.rb +++ b/spec/models/address_spec.rb @@ -10,11 +10,14 @@ describe Address, '.extract_params' do it 'returns params hash'do Fabricate(:country, iso:'EE') ph = { postalInfo: { name: "fred", addr: { cc: 'EE', city: 'Village', street: [ 'street1', 'street2' ] } } } - expect(Address.extract_attributes(ph[:postalInfo][:addr])).to eq( { - city: 'Village', - country_id: 1, - street: 'street1', - street2: 'street2' + expect(Address.extract_attributes(ph[:postalInfo])).to eq( { + international_address_attributes: { + name: 'fred', + city: 'Village', + country_id: 1, + street: 'street1', + street2: 'street2', + } } ) end end diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb index 3fae6fc92..6fca27485 100644 --- a/spec/models/contact_spec.rb +++ b/spec/models/contact_spec.rb @@ -1,7 +1,8 @@ require "rails_helper" describe Contact do - it { should have_one(:address) } + it { should have_one(:local_address) } + it { should have_one(:international_address) } context 'with invalid attribute' do before(:each) { @contact = Fabricate(:contact) } @@ -22,7 +23,6 @@ describe Contact do expect(@contact.errors.messages).to match_array({ :code=>["Required parameter missing - code"], - :name=>["Required parameter missing - name"], :phone=>["Required parameter missing - phone", "Phone nr is invalid"], :email=>["Required parameter missing - email", "Email is invalid"], :ident=>["Required parameter missing - ident"] @@ -90,8 +90,7 @@ describe Contact, '.extract_params' do ph = { id: '123123', email: 'jdoe@example.com', postalInfo: { name: "fred", addr: { cc: 'EE' } } } expect(Contact.extract_attributes(ph)).to eq( { code: '123123', - email: 'jdoe@example.com', - name: 'fred' + email: 'jdoe@example.com' } ) end end