diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 6ff00c231..a19a0d772 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -524,7 +524,6 @@ class Epp::Domain < Domain ### TRANSFER ### - # rubocop: disable Metrics/PerceivedComplexity # rubocop: disable Metrics/CyclomaticComplexity def transfer(frame, action, current_user) case action @@ -552,29 +551,15 @@ class Epp::Domain < Domain oc = c.deep_clone oc.code = nil oc.registrar_id = registrar_id + oc.copy_from_id = c.id oc.prefix_code oc.save!(validate: false) oc end - def transfer_contact(contact_id, registrar_id) - oc = Contact.find(contact_id) # n+1 workaround - oc.registrar_id = registrar_id - oc.generate_new_code! - oc.save!(validate: false) - oc - end - def transfer_registrant(registrar_id) return if registrant.registrar_id == registrar_id - - is_other_domains_contact = DomainContact.where('contact_id = ? AND domain_id != ?', registrant_id, id).count > 0 - if registrant.registrant_domains.count > 1 || is_other_domains_contact - oc = copy_and_transfer_contact(registrant_id, registrar_id) - self.registrant_id = oc.id - else - transfer_contact(registrant_id, registrar_id) - end + self.registrant_id = copy_and_transfer_contact(registrant_id, registrar_id).id end def transfer_domain_contacts(registrar_id) @@ -582,22 +567,14 @@ class Epp::Domain < Domain contacts.each do |c| next if copied_ids.include?(c.id) || c.registrar_id == registrar_id - is_other_domains_contact = DomainContact.where('contact_id = ? AND domain_id != ?', c.id, id).count > 0 - # if contact used to be owner contact but was copied, then contact must be transferred - # (registrant_id_was != c.id) - if c.domains.count > 1 || is_other_domains_contact - # copy contact - if registrant_id_was == c.id # owner contact was copied previously, do not copy it again - oc = OpenStruct.new(id: registrant_id) - else - oc = copy_and_transfer_contact(c.id, registrar_id) - end - - domain_contacts.where(contact_id: c.id).update_all({ contact_id: oc.id }) # n+1 workaround - copied_ids << c.id + if registrant_id_was == c.id # registrant was copied previously, do not copy it again + oc = OpenStruct.new(id: registrant_id) else - transfer_contact(c.id, registrar_id) + oc = copy_and_transfer_contact(c.id, registrar_id) end + + domain_contacts.where(contact_id: c.id).update_all({ contact_id: oc.id }) # n+1 workaround + copied_ids << c.id end end diff --git a/config/database-example-development.yml b/config/database-example-development.yml index 6cfce0d79..8bcaf097f 100644 --- a/config/database-example-development.yml +++ b/config/database-example-development.yml @@ -21,3 +21,21 @@ api_log_development: registrant_write_development: <<: *default database: registry_development + + +test: + <<: *default + database: registry_test + +whois_test: + <<: *default + database: registry_whois_test + +api_log_test: + <<: *default + database: registry_api_log_test + +registrant_write_test: + <<: *default + database: registry_test + diff --git a/db/migrate/20150910113839_add_copy_from_id.rb b/db/migrate/20150910113839_add_copy_from_id.rb new file mode 100644 index 000000000..c023750ff --- /dev/null +++ b/db/migrate/20150910113839_add_copy_from_id.rb @@ -0,0 +1,5 @@ +class AddCopyFromId < ActiveRecord::Migration + def change + add_column :contacts, :copy_from_id, :integer + end +end diff --git a/db/schema-read-only.rb b/db/schema-read-only.rb index 79739bb06..7bcf1f877 100644 --- a/db/schema-read-only.rb +++ b/db/schema-read-only.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150825125118) do +ActiveRecord::Schema.define(version: 20150910113839) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -201,6 +201,7 @@ ActiveRecord::Schema.define(version: 20150825125118) do t.integer "legacy_id" t.string "statuses", array: true t.hstore "status_notes" + t.integer "copy_from_id" end add_index "contacts", ["code"], name: "index_contacts_on_code", using: :btree diff --git a/db/structure.sql b/db/structure.sql index 74cddb0e9..b2c6c0bca 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -596,7 +596,8 @@ CREATE TABLE contacts ( state character varying, legacy_id integer, statuses character varying[], - status_notes hstore + status_notes hstore, + copy_from_id integer ); @@ -4928,3 +4929,5 @@ INSERT INTO schema_migrations (version) VALUES ('20150810114746'); INSERT INTO schema_migrations (version) VALUES ('20150825125118'); +INSERT INTO schema_migrations (version) VALUES ('20150910113839'); + diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb index d24ba37fe..0d24e2cfa 100644 --- a/spec/epp/domain_spec.rb +++ b/spec/epp/domain_spec.rb @@ -1181,9 +1181,10 @@ describe 'EPP Domain', epp: true do end # all domain contacts should be under registrar2 now + domain.reload domain.registrant.reload domain.registrant.registrar_id.should == @registrar2.id - domain.registrant.id.should == original_oc_id + domain.registrant.id.should_not == original_oc_id # must generate new code domain.registrant.code.should_not == original_oc_code @@ -1289,8 +1290,7 @@ describe 'EPP Domain', epp: true do # all domain contacts should be under registrar2 now domain.reload domain.registrant.registrar_id.should == @registrar2.id - # registrant should not be a new record - domain.registrant.id.should == original_oc_id + domain.registrant.id.should_not == original_oc_id # old contact must not change old_contact.registrar_id.should == @registrar1.id @@ -1305,8 +1305,8 @@ describe 'EPP Domain', epp: true do # there should be 2 references to the new contact domain.domain_contacts.where(contact_id: new_contact.id).count.should == 2 - # there should be only one new contact object - (original_contact_count + 1).should == Contact.count + # there should be four new contact object + (original_contact_count + 4).should == Contact.count # and no new references original_domain_contact_count.should == DomainContact.count @@ -1344,7 +1344,7 @@ describe 'EPP Domain', epp: true do domain.reload domain.registrant.registrar_id.should == @registrar2.id # registrant should not be a new record - domain.registrant.id.should == original_oc_id + domain.registrant.id.should_not == original_oc_id # old contact must not change old_contact.registrar_id.should == @registrar1.id @@ -1367,8 +1367,8 @@ describe 'EPP Domain', epp: true do # there should be 1 reference to the new contact 2 (tech) domain.domain_contacts.where(contact_id: new_contact_2.id).count.should == 1 - # there should be only two new contact objects - (original_contact_count + 2).should == Contact.count + # there should be four new contact objects + (original_contact_count + 5).should == Contact.count # and no new references original_domain_contact_count.should == DomainContact.count @@ -1435,6 +1435,43 @@ describe 'EPP Domain', epp: true do original_contacts_codes.sort.should == domain.contacts.pluck(:code).sort end + fit 'transfers domain contact should populate copy_from_id' do + d = Fabricate(:domain) + d.tech_contacts << domain.registrant + + original_oc_id = domain.registrant.id + original_oc_code = domain.registrant.code + domain.registrant.copy_from_id.should == nil + + original_contact_codes = domain.contacts.pluck(:code) + + pw = domain.auth_info + xml = domain_transfer_xml({ + name: { value: domain.name }, + authInfo: { pw: { value: pw } } + }) + + login_as :registrar2 do + response = epp_plain_request(xml) + response[:msg].should == 'Command completed successfully' + response[:result_code].should == '1000' + end + + # all domain contacts should be under registrar2 now + domain.reload + domain.registrant.registrar_id.should == @registrar2.id + # registrant should be a new record + domain.registrant.id.should_not == original_oc_id + domain.registrant.copy_from_id.should == original_oc_id + # must generate new code + domain.registrant.code.should_not == original_oc_code + + domain.contacts.each do |c| + c.registrar_id.should == @registrar2.id + original_contact_codes.include?(c.code).should_not == true + end + end + it 'should not creates transfer without password' do xml = domain_transfer_xml({ name: { value: domain.name }