From 3673c69319b87c82bc8b279583f3d463f347c50b Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Wed, 1 Aug 2018 14:57:41 +0300 Subject: [PATCH 1/7] Add Registrant/Contacts endpoint --- .../api/v1/registrant/contacts_controller.rb | 47 +++++++++++ config/routes.rb | 1 + .../registrant_api_contacts_test.rb | 79 +++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 app/controllers/api/v1/registrant/contacts_controller.rb create mode 100644 test/integration/api/registrant/registrant_api_contacts_test.rb diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb new file mode 100644 index 000000000..31d56885b --- /dev/null +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -0,0 +1,47 @@ +require 'rails5_api_controller_backport' +require 'auth_token/auth_token_decryptor' + +module Api + module V1 + module Registrant + class ContactsController < BaseController + before_action :set_contacts_pool + + def index + limit = params[:limit] || 200 + offset = params[:offset] || 0 + + if limit.to_i > 200 || limit.to_i < 1 + render(json: { errors: [{ limit: ['parameter is out of range'] }] }, + status: :bad_request) && return + end + + if offset.to_i.negative? + render(json: { errors: [{ offset: ['parameter is out of range'] }] }, + status: :bad_request) && return + end + + @contacts = @contacts_pool.limit(limit).offset(offset) + render json: @contacts + end + + def show + @contact = @contacts_pool.find_by(uuid: params[:uuid]) + + if @contact + render json: @contact + else + render json: { errors: ['Contact not found'] }, status: :not_found + end + end + + private + + def set_contacts_pool + country_code, ident = current_user.registrant_ident.to_s.split '-' + @contacts_pool = Contact.where(country_code: country_code, ident: ident) + end + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 3ae18a7cd..9229eb1b2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -24,6 +24,7 @@ Rails.application.routes.draw do post 'auth/eid', to: 'auth#eid' resources :domains, only: [:index] + resources :contacts, only: %i[index show] end end end diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb new file mode 100644 index 000000000..a3367dd58 --- /dev/null +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -0,0 +1,79 @@ +require 'test_helper' +require 'auth_token/auth_token_creator' + +class RegistrantApiContactsTest < ActionDispatch::IntegrationTest + def setup + super + + @user = users(:registrant) + @auth_headers = { 'HTTP_AUTHORIZATION' => auth_token } + end + + def test_root_returns_domain_list + get '/api/v1/registrant/contacts', {}, @auth_headers + assert_equal(200, response.status) + + json_body = JSON.parse(response.body, symbolize_names: true) + assert_equal(2, json_body.count) + array_of_contact_codes = json_body.map { |x| x[:code] } + assert(array_of_contact_codes.include?('william-001')) + assert(array_of_contact_codes.include?('william-002')) + end + + def test_root_accepts_limit_and_offset_parameters + get '/api/v1/registrant/contacts', { 'limit' => 1, 'offset' => 0 }, @auth_headers + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal(200, response.status) + assert_equal(1, response_json.count) + + get '/api/v1/registrant/contacts', {}, @auth_headers + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal(2, response_json.count) + end + + def test_root_does_not_accept_limit_higher_than_200 + get '/api/v1/registrant/contacts', { 'limit' => 400, 'offset' => 0 }, @auth_headers + assert_equal(400, response.status) + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal({ errors: [{ limit: ['parameter is out of range'] }] }, response_json) + end + + def test_root_does_not_accept_offset_lower_than_0 + get '/api/v1/registrant/contacts', { 'limit' => 200, 'offset' => "-10" }, @auth_headers + assert_equal(400, response.status) + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal({ errors: [{ offset: ['parameter is out of range'] }] }, response_json) + end + + def test_root_returns_401_without_authorization + get '/api/v1/registrant/contacts', {}, {} + assert_equal(401, response.status) + json_body = JSON.parse(response.body, symbolize_names: true) + + assert_equal({ errors: ['Not authorized'] }, json_body) + end + + def test_details_returns_401_without_authorization + get '/api/v1/registrant/contacts/c0a191d5-3793-4f0b-8f85-491612d0293e', {}, {} + assert_equal(401, response.status) + json_body = JSON.parse(response.body, symbolize_names: true) + + assert_equal({ errors: ['Not authorized'] }, json_body) + end + + def test_details_returns_404_for_non_existent_contact + get '/api/v1/registrant/contacts/some-random-uuid', {}, @auth_headers + assert_equal(404, response.status) + json_body = JSON.parse(response.body, symbolize_names: true) + + assert_equal({ errors: ['Contact not found'] }, json_body) + end + + private + + def auth_token + token_creator = AuthTokenCreator.create_with_defaults(@user) + hash = token_creator.token_in_hash + "Bearer #{hash[:access_token]}" + end +end From 079800172552ab94ff5bcc360288d76c5c2828ff Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Tue, 7 Aug 2018 15:04:37 +0300 Subject: [PATCH 2/7] Make returned API errors more consistent --- app/controllers/api/v1/registrant/contacts_controller.rb | 2 +- .../api/registrant/registrant_api_contacts_test.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index 31d56885b..f252b3acd 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -31,7 +31,7 @@ module Api if @contact render json: @contact else - render json: { errors: ['Contact not found'] }, status: :not_found + render json: { errors: [{ base: ['Contact not found'] }] }, status: :not_found end end diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb index a3367dd58..ff51494af 100644 --- a/test/integration/api/registrant/registrant_api_contacts_test.rb +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -50,7 +50,7 @@ class RegistrantApiContactsTest < ActionDispatch::IntegrationTest assert_equal(401, response.status) json_body = JSON.parse(response.body, symbolize_names: true) - assert_equal({ errors: ['Not authorized'] }, json_body) + assert_equal({ errors: [base: ['Not authorized']] }, json_body) end def test_details_returns_401_without_authorization @@ -58,7 +58,7 @@ class RegistrantApiContactsTest < ActionDispatch::IntegrationTest assert_equal(401, response.status) json_body = JSON.parse(response.body, symbolize_names: true) - assert_equal({ errors: ['Not authorized'] }, json_body) + assert_equal({ errors: [base: ['Not authorized']] }, json_body) end def test_details_returns_404_for_non_existent_contact @@ -66,7 +66,7 @@ class RegistrantApiContactsTest < ActionDispatch::IntegrationTest assert_equal(404, response.status) json_body = JSON.parse(response.body, symbolize_names: true) - assert_equal({ errors: ['Contact not found'] }, json_body) + assert_equal({ errors: [base: ['Contact not found']] }, json_body) end private From 06dc954167b48f1854611282d02537cf6ced3a56 Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Wed, 8 Aug 2018 09:15:18 +0300 Subject: [PATCH 3/7] Make tests inherit from ApplicationIntegrationTest class --- test/integration/api/registrant/registrant_api_contacts_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb index ff51494af..c73c4a503 100644 --- a/test/integration/api/registrant/registrant_api_contacts_test.rb +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -1,7 +1,7 @@ require 'test_helper' require 'auth_token/auth_token_creator' -class RegistrantApiContactsTest < ActionDispatch::IntegrationTest +class RegistrantApiContactsTest < ApplicationIntegrationTest def setup super From b18db190355fb38f5b7891ef32dd284a8025e39b Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Thu, 9 Aug 2018 14:07:06 +0300 Subject: [PATCH 4/7] Fix error introduced by merge conflict --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 7a802a7a1..6af6623f8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,7 +23,7 @@ Rails.application.routes.draw do namespace :registrant do post 'auth/eid', to: 'auth#eid' - resources :domains, only: %i[index, show], param: :uuid + resources :domains, only: %i[index show], param: :uuid resources :contacts, only: %i[index show], param: :uuid end end From 4cc06692868e15a910b41beb17658d309396cda9 Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Thu, 9 Aug 2018 15:04:22 +0300 Subject: [PATCH 5/7] Add business registry support for contacts controller --- .../api/v1/registrant/contacts_controller.rb | 18 +++++++--- .../api/v1/registrant/domains_controller.rb | 2 -- .../registrant/contacts_controller.rb | 2 +- .../registrant_api_contacts_test.rb | 33 +++++++++++++++++-- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index f252b3acd..2c8a1f70e 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -1,6 +1,3 @@ -require 'rails5_api_controller_backport' -require 'auth_token/auth_token_decryptor' - module Api module V1 module Registrant @@ -39,7 +36,20 @@ module Api def set_contacts_pool country_code, ident = current_user.registrant_ident.to_s.split '-' - @contacts_pool = Contact.where(country_code: country_code, ident: ident) + associated_domain_ids = begin + BusinessRegistryCache.fetch_by_ident_and_cc(ident, country_code).associated_domain_ids + end + + available_contacts_ids = begin + DomainContact.where(domain_id: associated_domain_ids).pluck(:contact_id) | + Domain.where(id: associated_domain_ids).pluck(:registrant_id) + end + + @contacts_pool = Contact.where(id: available_contacts_ids) + rescue Soap::Arireg::NotAvailableError => error + Rails.logger.fatal("[EXCEPTION] #{error}") + render json: { errors: [{ base: ["Business Registry Not Available"] }] }, + status: :service_unavailable and return end end end diff --git a/app/controllers/api/v1/registrant/domains_controller.rb b/app/controllers/api/v1/registrant/domains_controller.rb index 27b7b6125..7209f8a10 100644 --- a/app/controllers/api/v1/registrant/domains_controller.rb +++ b/app/controllers/api/v1/registrant/domains_controller.rb @@ -1,5 +1,3 @@ -require 'rails5_api_controller_backport' - module Api module V1 module Registrant diff --git a/app/controllers/registrant/contacts_controller.rb b/app/controllers/registrant/contacts_controller.rb index f73650de2..267b4d68d 100644 --- a/app/controllers/registrant/contacts_controller.rb +++ b/app/controllers/registrant/contacts_controller.rb @@ -26,4 +26,4 @@ class Registrant::ContactsController < RegistrantController BusinessRegistryCache.fetch_by_ident_and_cc(ident, ident_cc).associated_domain_ids end end -end \ No newline at end of file +end diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb index c73c4a503..28dd50d76 100644 --- a/test/integration/api/registrant/registrant_api_contacts_test.rb +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -5,19 +5,30 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest def setup super + @original_registry_time = Setting.days_to_keep_business_registry_cache + Setting.days_to_keep_business_registry_cache = 1 + travel_to Time.zone.parse('2010-07-05') + @user = users(:registrant) @auth_headers = { 'HTTP_AUTHORIZATION' => auth_token } end + def teardown + super + + Setting.days_to_keep_business_registry_cache = @original_registry_time + travel_back + end + def test_root_returns_domain_list get '/api/v1/registrant/contacts', {}, @auth_headers assert_equal(200, response.status) json_body = JSON.parse(response.body, symbolize_names: true) - assert_equal(2, json_body.count) + assert_equal(5, json_body.count) array_of_contact_codes = json_body.map { |x| x[:code] } assert(array_of_contact_codes.include?('william-001')) - assert(array_of_contact_codes.include?('william-002')) + assert(array_of_contact_codes.include?('jane-001')) end def test_root_accepts_limit_and_offset_parameters @@ -28,7 +39,23 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest get '/api/v1/registrant/contacts', {}, @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) - assert_equal(2, response_json.count) + assert_equal(5, response_json.count) + end + + def test_get_contact_details_by_uuid + get '/api/v1/registrant/contacts/0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb', {}, @auth_headers + assert_equal(200, response.status) + + contact = JSON.parse(response.body, symbolize_names: true) + assert_equal('william@inbox.test', contact[:email]) + end + + def test_get_contact_details_by_uuid_returns_404_for_non_existent_contact + get '/api/v1/registrant/contacts/nonexistent-uuid', {}, @auth_headers + assert_equal(404, response.status) + + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal({ errors: [{ base: ['Contact not found'] }] }, response_json) end def test_root_does_not_accept_limit_higher_than_200 From 256d2b7de424b914c7cd36628d73f58de3420086 Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Thu, 9 Aug 2018 15:24:21 +0300 Subject: [PATCH 6/7] Add test for error in business registry --- .../api/v1/registrant/contacts_controller.rb | 2 +- .../api/registrant/registrant_api_contacts_test.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index 2c8a1f70e..5db175265 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -48,7 +48,7 @@ module Api @contacts_pool = Contact.where(id: available_contacts_ids) rescue Soap::Arireg::NotAvailableError => error Rails.logger.fatal("[EXCEPTION] #{error}") - render json: { errors: [{ base: ["Business Registry Not Available"] }] }, + render json: { errors: [{ base: ["Business Registry not available"] }] }, status: :service_unavailable and return end end diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb index 28dd50d76..ddeaee9f3 100644 --- a/test/integration/api/registrant/registrant_api_contacts_test.rb +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -50,6 +50,17 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest assert_equal('william@inbox.test', contact[:email]) end + def test_root_returns_503_when_business_registry_is_not_available + raise_not_available = -> (a, b) { raise Soap::Arireg::NotAvailableError.new({}) } + BusinessRegistryCache.stub :fetch_by_ident_and_cc, raise_not_available do + get '/api/v1/registrant/contacts', {}, @auth_headers + + assert_equal(503, response.status) + response_json = JSON.parse(response.body, symbolize_names: true) + assert_equal({ errors: [base: ['Business Registry not available']] }, response_json) + end + end + def test_get_contact_details_by_uuid_returns_404_for_non_existent_contact get '/api/v1/registrant/contacts/nonexistent-uuid', {}, @auth_headers assert_equal(404, response.status) From c186929be4704ba2f1ea26a3b4e86286dce1ac26 Mon Sep 17 00:00:00 2001 From: Maciej Szlosarczyk Date: Thu, 9 Aug 2018 15:28:43 +0300 Subject: [PATCH 7/7] Use single quote instead of double quotes --- app/controllers/api/v1/registrant/contacts_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index 5db175265..de5ef9dcf 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -48,7 +48,7 @@ module Api @contacts_pool = Contact.where(id: available_contacts_ids) rescue Soap::Arireg::NotAvailableError => error Rails.logger.fatal("[EXCEPTION] #{error}") - render json: { errors: [{ base: ["Business Registry not available"] }] }, + render json: { errors: [{ base: ['Business Registry not available'] }] }, status: :service_unavailable and return end end