From eb64b3aca4b31be44a99b56230b5fed2b15b4086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Tue, 29 Mar 2022 10:39:26 +0300 Subject: [PATCH] Modifications for updating business and private contacts --- .../api/v1/registrant/contacts_controller.rb | 10 +- app/models/action.rb | 2 +- app/models/contact.rb | 13 ++ app/models/registrant_user.rb | 82 +++++------- app/views/epp/poll/_action.xml.builder | 10 -- app/views/epp/poll/_extension.xml.builder | 18 +++ app/views/epp/poll/poll_req.xml.builder | 19 ++- config/routes.rb | 5 +- .../registrant_user_creation_test.rb | 43 ------- test/models/registrant_user_test.rb | 120 ++++++++++++------ 10 files changed, 159 insertions(+), 163 deletions(-) delete mode 100644 app/views/epp/poll/_action.xml.builder create mode 100644 app/views/epp/poll/_extension.xml.builder diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index 8e8b46631..b196c567a 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -34,15 +34,15 @@ module Api end end - def do_need_update_contact - result = current_registrant_user.do_need_update_contact? + def do_need_update_contacts + result = current_registrant_user.do_need_update_contacts? render json: { update_contacts: result[:result], counter: result[:counter] } end - def update_company_contacts - companies = current_registrant_user.update_company_contacts + def update_contacts + contacts = current_registrant_user.update_contacts - render json: { message: 'get it', companies: companies } + render json: { message: 'get it', contacts: contacts } end def update diff --git a/app/models/action.rb b/app/models/action.rb index c87467949..8a822f867 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -32,7 +32,7 @@ class Action < ApplicationRecord subactions.map do |a| { - code: a.contact&.code, + code: a.contact.code, avail: 0, reason: 'in use', } diff --git a/app/models/contact.rb b/app/models/contact.rb index 84d4ba962..8bb471e47 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -30,6 +30,19 @@ class Contact < ApplicationRecord .where('success = false and verified_at IS NOT NULL') } + scope :with_different_company_name, (lambda do |company| + where("ident = ? AND ident_country_code = 'EE' AND name != ?", + company.registration_number, + company.company_name) + end) + + scope :with_different_registrant_name, (lambda do |user| + where('ident = ? AND ident_country_code = ? AND UPPER(name) != UPPER(?)', + user.ident, + user.country.alpha2, + user.username) + end) + NAME_REGEXP = /([\u00A1-\u00B3\u00B5-\u00BF\u0021-\u0026\u0028-\u002C\u003A-\u0040]| [\u005B-\u005F\u007B-\u007E\u2040-\u206F\u20A0-\u20BF\u2100-\u218F])/x diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index bbe4044b6..96fef635e 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -26,13 +26,13 @@ class RegistrantUser < User [] end - def do_need_update_contact? - return { result: false, counter: 0 } if companies.blank? - + def do_need_update_contacts? counter = 0 + + counter += Contact.with_different_registrant_name(self).size + companies.each do |company| - counter += Contact.where(ident: company.registration_number, ident_country_code: 'EE')&. - reject { |contact| contact.name == company.company_name }.size + counter += Contact.with_different_company_name(company).size end return { result: true, counter: counter } if counter.positive? @@ -40,39 +40,35 @@ class RegistrantUser < User { result: false, counter: 0 } end - def update_company_contacts - return [] if companies.blank? - + def update_contacts + user = self + contacts = [] + contacts.concat Contact.with_different_registrant_name(user) + .each{ |c| c.write_attribute(:name, user.username) } companies.each do |company| - contacts = Contact.where(ident: company.registration_number, ident_country_code: 'EE') - - next if contacts.blank? - - contacts.each do |contact| - next if company.company_name == contact.name - - update_company_name(contact: contact, company: company) - end + contacts.concat Contact.with_different_company_name(company) + .each{ |c| c.write_attribute(:name, company.company_name) } end + + return [] if contacts.blank? - companies + grouped_contacts = contacts.group_by(&:registrar_id) + grouped_contacts.each do |registrar_id, contacts| + bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 + contacts.each do |c| + if c.save(validate: false) + action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) + end + end + notify_registrar_contacts_updated(action: bulk_action || action, + registrar_id: registrar_id) + end + contacts end - def update_company_name(contact:, company:) - old_contact_name = contact.name - contact.name = company.company_name - - contact.save(validate: false) - - notify_registrar_data_updated(company_name: company.company_name, - old_contact_name: old_contact_name, - contact: contact) - end - - def notify_registrar_data_updated(company_name:, old_contact_name:, contact:) - contact.registrar.notifications.create!( - text: "Contact update: #{contact.id} name updated from #{old_contact_name} to #{company_name} by the registry" - ) + def notify_registrar_contacts_updated(action:, registrar_id:) + registrar = Registrar.find(registrar_id) + registrar.notify(action) if registrar end def contacts(representable: true) @@ -111,24 +107,6 @@ class RegistrantUser < User username.split.second end - # rubocop:disable Metrics/MethodLength - def update_related_contacts - grouped_contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) - .where('UPPER(name) != UPPER(?)', username) - .includes(:registrar) - .group_by(&:registrar) - grouped_contacts.each do |registrar, contacts| - bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 - contacts.each do |c| - if c.update(name: username) - action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) - end - end - registrar.notify(bulk_action || action) - end - end - # rubocop:enable Metrics/MethodLength - class << self def find_or_create_by_api_data(user_data = {}) return false unless user_data[:ident] @@ -165,8 +143,6 @@ class RegistrantUser < User user = find_or_create_by(registrant_ident: "#{user_data[:country_code]}-#{user_data[:ident]}") user.username = "#{user_data[:first_name]} #{user_data[:last_name]}" user.save - - user.update_related_contacts user end end diff --git a/app/views/epp/poll/_action.xml.builder b/app/views/epp/poll/_action.xml.builder deleted file mode 100644 index 37f2acccb..000000000 --- a/app/views/epp/poll/_action.xml.builder +++ /dev/null @@ -1,10 +0,0 @@ -builder.extension do - builder.tag!('changePoll:changeData', - 'xmlns:changePoll' => Xsd::Schema.filename(for_prefix: 'changePoll', for_version: '1.0')) do - builder.tag!('changePoll:operation', action.operation) - builder.tag!('changePoll:date', action.created_at.utc.xmlschema) - builder.tag!('changePoll:svTRID', action.id) - builder.tag!('changePoll:who', action.user) - builder.tag!('changePoll:reason', 'Auto-update according to official data') if action.bulk_action? - end -end diff --git a/app/views/epp/poll/_extension.xml.builder b/app/views/epp/poll/_extension.xml.builder new file mode 100644 index 000000000..a26e3db8b --- /dev/null +++ b/app/views/epp/poll/_extension.xml.builder @@ -0,0 +1,18 @@ +builder.extension do + builder.tag!('changePoll:changeData', + 'xmlns:changePoll' => Xsd::Schema.filename(for_prefix: 'changePoll', + for_version: '1.0')) do + case type + when 'action' + builder.tag!('changePoll:operation', obj.operation) + builder.tag!('changePoll:date', obj.created_at.utc.xmlschema) + builder.tag!('changePoll:svTRID', obj.id) + builder.tag!('changePoll:who', obj.user) + if obj.bulk_action? + builder.tag!('changePoll:reason', 'Auto-update according to official data') + end + when 'state' + builder.tag!('changePoll:operation', obj) + end + end +end \ No newline at end of file diff --git a/app/views/epp/poll/poll_req.xml.builder b/app/views/epp/poll/poll_req.xml.builder index f6688fb48..0a916e6ad 100644 --- a/app/views/epp/poll/poll_req.xml.builder +++ b/app/views/epp/poll/poll_req.xml.builder @@ -29,18 +29,15 @@ xml.epp_head do if @notification.action || @notification.registry_lock? if @notification.registry_lock? state = @notification.text.include?('unlocked') ? 'unlock' : 'lock' - xml.extension do - xml.tag!('changePoll:changeData', - 'xmlns:changePoll': Xsd::Schema.filename(for_prefix: 'changePoll')) do - xml.tag!('changePoll:operation', state) - end - end + render(partial: 'epp/poll/extension', + locals: { builder: xml, + obj: state, + type: 'state' }) else - render(partial: 'epp/poll/action', - locals: { - builder: xml, - action: @notification.action, - }) + render(partial: 'epp/poll/extension', + locals: { builder: xml, + obj: @notification.action, + type: 'action' }) end end diff --git a/config/routes.rb b/config/routes.rb index 79807729a..a2a4556f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -129,8 +129,9 @@ Rails.application.routes.draw do resource :registry_lock, only: %i[create destroy] end resources :contacts, only: %i[index show update], param: :uuid do - get 'do_need_update_contact', to: 'contacts#do_need_update_contact', as: :do_need_update_contact - post 'update_company_contacts', to: 'contacts#update_company_contacts', as: :update_company_contacts + get 'do_need_update_contacts', to: 'contacts#do_need_update_contacts', + as: :do_need_update_contacts + post 'update_contacts', to: 'contacts#update_contacts', as: :update_contacts end resources :companies, only: %i[index] end diff --git a/test/models/registrant_user/registrant_user_creation_test.rb b/test/models/registrant_user/registrant_user_creation_test.rb index f183c94dc..a32191db8 100644 --- a/test/models/registrant_user/registrant_user_creation_test.rb +++ b/test/models/registrant_user/registrant_user_creation_test.rb @@ -29,47 +29,4 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase user = User.find_by(registrant_ident: 'US-1234') assert_equal('John Smith', user.username) end - - def test_updates_related_contacts_name_if_different_from_e_identity - registrars = [registrars(:bestnames), registrars(:goodnames)] - contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william)] - contacts.each do |c| - c.update(ident: '39708290276', ident_country_code: 'EE') - end - - user_data = { - ident: '39708290276', - first_name: 'John', - last_name: 'Doe', - } - - RegistrantUser.find_or_create_by_api_data(user_data) - - user = User.find_by(registrant_ident: 'EE-39708290276') - assert_equal('John Doe', user.username) - - contacts.each do |c| - c.reload - assert_equal user.username, c.name - assert user.actions.find_by(operation: :update, contact_id: c.id) - end - - bulk_action = BulkAction.find_by(user_id: user.id, operation: :bulk_update) - assert_equal 2, bulk_action.subactions.size - - registrars.each do |r| - notification = r.notifications.unread.order('created_at DESC').take - if r == registrars(:bestnames) - assert_equal '2 contacts have been updated by registrant', notification.text - assert_equal 'BulkAction', notification.attached_obj_type - assert_equal bulk_action.id, notification.attached_obj_id - assert_equal bulk_action.id, notification.action_id - else - assert_equal 'Contact william-002 has been updated by registrant', notification.text - refute notification.action_id - refute notification.attached_obj_id - refute notification.attached_obj_type - end - end - end end diff --git a/test/models/registrant_user_test.rb b/test/models/registrant_user_test.rb index 2b1d6a880..81e57fa72 100644 --- a/test/models/registrant_user_test.rb +++ b/test/models/registrant_user_test.rb @@ -32,30 +32,61 @@ class RegistrantUserTest < ActiveSupport::TestCase assert_equal Country.new('US'), user.country end - def test_should_update_org_contact_if_data_from_business_registry_dismatch + def test_should_update_contacts_if_names_dismatch assert_equal 'US-1234', @user.registrant_ident - org = contacts(:acme_ltd) - org.ident_country_code = 'EE' - org.save(validate: false) - org.reload + registrars = [registrars(:bestnames), registrars(:goodnames)] + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william), + contacts(:acme_ltd), contacts(:registrar_ltd)] + contacts.each do |c| + if c.ident_type == 'priv' + c.ident = @user.ident + else + c.ident_country_code = 'EE' + c.registrar = registrars(:bestnames) + end + c.save(validate: false) + end - company = Company.new(org.ident, "ace") + company_one = Company.new(contacts(:acme_ltd).ident, 'ace') + company_two = Company.new(contacts(:registrar_ltd).ident, 'acer') - Spy.on(@user, :companies).and_return([company]) - @user.update_company_contacts - org.reload + Spy.on(@user, :companies).and_return([company_one, company_two]) + @user.update_contacts - assert_equal org.name, company.company_name + contacts.each do |c| + c.reload + assert_equal @user.username, c.name if c.ident_type == 'priv' + assert @user.actions.find_by(operation: :update, contact_id: c.id) + end + + bulk_action = @user.actions.where(operation: :bulk_update).last + + assert_equal 4, bulk_action.subactions.size + + registrars.each do |r| + notification = r.notifications.unread.order('created_at DESC').take + if r == registrars(:bestnames) + assert_equal '4 contacts have been updated by registrant', notification.text + assert_equal 'BulkAction', notification.attached_obj_type + assert_equal bulk_action.id, notification.attached_obj_id + assert_equal bulk_action.id, notification.action_id + else + assert_equal 'Contact william-002 has been updated by registrant', notification.text + refute notification.action_id + refute notification.attached_obj_id + refute notification.attached_obj_type + end + end end def test_queries_company_register_for_associated_companies assert_equal 'US-1234', @user.registrant_ident - company = Company.new("acme", "ace") + company = Company.new('acme', 'ace') company_register = Minitest::Mock.new company_register.expect(:representation_rights, [company], [{ citizen_personal_code: '1234', - citizen_country_code: 'USA' }]) + citizen_country_code: 'USA' }]) assert_equal [company], @user.companies(company_register) company_register.verify @@ -63,58 +94,71 @@ class RegistrantUserTest < ActiveSupport::TestCase def test_should_return_zero_count_of_companies assert_equal 'US-1234', @user.registrant_ident - org = contacts(:acme_ltd) - org.ident_country_code = 'EE' - org.save(validate: false) - org.reload + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william), + contacts(:acme_ltd), contacts(:registrar_ltd)] - company_one = Company.new(org.ident, 'Acme Ltd') + contacts.each do |c| + if c.ident_type == 'priv' + c.ident = @user.ident + c.name = @user.username + else + c.ident_country_code = 'EE' + end + c.save(validate: false) + end - Spy.on(@user, :companies).and_return([company_one]) - response = @user.do_need_update_contact? - org.reload + company_one = Company.new(contacts(:acme_ltd).ident, 'Acme Ltd') + company_two = Company.new(contacts(:registrar_ltd).ident, 'Registrar Ltd') + + Spy.on(@user, :companies).and_return([company_one, company_two]) + response = @user.do_need_update_contacts? assert_equal response[:counter], 0 end - def test_should_return_count_of_contact_which_should_be_updated + def test_should_return_count_of_contacts_which_should_be_updated assert_equal 'US-1234', @user.registrant_ident - org = contacts(:acme_ltd) - org.ident_country_code = 'EE' - org.save(validate: false) - org.reload + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william), + contacts(:acme_ltd), contacts(:registrar_ltd)] + contacts.each do |c| + if c.ident_type == 'priv' + c.ident = @user.ident + else + c.ident_country_code = 'EE' + end + c.save(validate: false) + end - company_one = Company.new(org.ident, 'ace') - company_two = Company.new(org.ident, 'acer') + company_one = Company.new(contacts(:acme_ltd).ident, 'ace') + company_two = Company.new(contacts(:registrar_ltd).ident, 'acer') Spy.on(@user, :companies).and_return([company_one, company_two]) - response = @user.do_need_update_contact? - org.reload + response = @user.do_need_update_contacts? - assert_equal response[:counter], 2 + assert_equal response[:counter], 5 end def test_returns_contacts - Contact.stub(:registrant_user_contacts, %w(john jane)) do - assert_equal %w(john jane), @user.contacts + Contact.stub(:registrant_user_contacts, %w[john jane]) do + assert_equal %w[john jane], @user.contacts end end def test_returns_direct_contacts - Contact.stub(:registrant_user_direct_contacts, %w(john jane)) do - assert_equal %w(john jane), @user.direct_contacts + Contact.stub(:registrant_user_direct_contacts, %w[john jane]) do + assert_equal %w[john jane], @user.direct_contacts end end def test_returns_domains - Domain.stub(:registrant_user_domains, %w(shop airport)) do - assert_equal %w(shop airport), @user.domains + Domain.stub(:registrant_user_domains, %w[shop airport]) do + assert_equal %w[shop airport], @user.domains end end def test_returns_administered_domains - Domain.stub(:registrant_user_administered_domains, %w(shop airport)) do - assert_equal %w(shop airport), @user.administered_domains + Domain.stub(:registrant_user_administered_domains, %w[shop airport]) do + assert_equal %w[shop airport], @user.administered_domains end end end