diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index a02fb4aa1..560a965f3 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -14,7 +14,7 @@ class Registrar::DomainsController < Registrar::DeppController # EPP controller if params[:q].length == 1 && params[:q][:name_matches].present? @domain = Domain.find_by(name: params[:q][:name_matches]) if @domain - redirect_to info_registrar_domains_path(domain_name: @domain.name) and return + redirect_to info_registrar_domains_url(domain_name: @domain.name) and return end end @@ -40,6 +40,20 @@ class Registrar::DomainsController < Registrar::DeppController # EPP controller end @domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i > 0 + + respond_to do |format| + format.html + format.csv do + domain_presenters = [] + + @domains.find_each do |domain| + domain_presenters << ::DomainPresenter.new(domain: domain, view: view_context) + end + + csv = Registrar::DomainListCSVPresenter.new(domains: domain_presenters, view: view_context).to_s + send_data(csv) + end + end end # rubocop: enable Metrics/PerceivedComplexity # rubocop: enable Metrics/CyclomaticComplexity diff --git a/app/presenters/domain_presenter.rb b/app/presenters/domain_presenter.rb index 2d0cfd791..266115b91 100644 --- a/app/presenters/domain_presenter.rb +++ b/app/presenters/domain_presenter.rb @@ -1,5 +1,5 @@ class DomainPresenter - delegate :name, :registrant_name, :registrant_id, to: :domain + delegate :name, :registrant_name, :registrant_id, :registrant_code, to: :domain def initialize(domain:, view:) @domain = domain diff --git a/app/presenters/registrar/domain_list_csv_presenter.rb b/app/presenters/registrar/domain_list_csv_presenter.rb new file mode 100644 index 000000000..d6f0c46bd --- /dev/null +++ b/app/presenters/registrar/domain_list_csv_presenter.rb @@ -0,0 +1,45 @@ +class Registrar::DomainListCSVPresenter + def initialize(domains:, view:) + @domains = domains + @view = view + end + + def to_s + table = CSV::Table.new([header]) + + domains.each do |domain| + table << domain_to_row(domain: domain) + end + + table.to_s + end + + private + + def header + columns = %w( + domain_name + registrant_name + registrant_code + expire_time + ) + + columns.map! { |column| view.t("registrar.domains.index.csv.#{column}") } + + CSV::Row.new(columns, [], true) + end + + def domain_to_row(domain:) + row = [] + row[0] = domain.name + row[1] = domain.registrant_name + row[2] = domain.registrant_code + row[3] = domain.expire_date + row + + CSV::Row.new([], row) + end + + attr_reader :domains + attr_reader :view +end diff --git a/app/views/registrar/domains/index.haml b/app/views/registrar/domains/index.haml index 587ef2b5e..45eb564b6 100644 --- a/app/views/registrar/domains/index.haml +++ b/app/views/registrar/domains/index.haml @@ -52,6 +52,10 @@   %button.btn.btn-default.js-reset-form = t(:clear_fields) + .row + .col-md-2 + = button_tag t('.export_csv_btn'), class: 'btn btn-primary export-domains-csv-btn', + formaction: registrar_domains_path(format: 'csv') %hr .row diff --git a/config/locales/registrar/domains.en.yml b/config/locales/registrar/domains.en.yml new file mode 100644 index 000000000..af0115a81 --- /dev/null +++ b/config/locales/registrar/domains.en.yml @@ -0,0 +1,10 @@ +en: + registrar: + domains: + index: + export_csv_btn: Export CSV + csv: + domain_name: Domain + registrant_name: Registrant name + registrant_code: Registrant code + expire_time: Date of expiry diff --git a/spec/features/registrar/domains/csv_export_spec.rb b/spec/features/registrar/domains/csv_export_spec.rb new file mode 100644 index 000000000..4d64c76c4 --- /dev/null +++ b/spec/features/registrar/domains/csv_export_spec.rb @@ -0,0 +1,13 @@ +require 'rails_helper' + +RSpec.feature 'CSV Export' do + background do + Setting.registrar_ip_whitelist_enabled = false + sign_in_to_registrar_area(user: FactoryGirl.create(:api_user)) + end + + scenario 'exports csv' do + visit registrar_domains_url + click_button t('registrar.domains.index.export_csv_btn') + end +end diff --git a/spec/presenters/domain_presenter_spec.rb b/spec/presenters/domain_presenter_spec.rb index 2209c01aa..9813311b9 100644 --- a/spec/presenters/domain_presenter_spec.rb +++ b/spec/presenters/domain_presenter_spec.rb @@ -119,6 +119,7 @@ RSpec.describe DomainPresenter do name registrant_name registrant_id + registrant_code ) domain_delegatable_attributes.each do |attribute_name| diff --git a/spec/presenters/registrar/domain_list_csv_presenter_spec.rb b/spec/presenters/registrar/domain_list_csv_presenter_spec.rb new file mode 100644 index 000000000..df4eec1fe --- /dev/null +++ b/spec/presenters/registrar/domain_list_csv_presenter_spec.rb @@ -0,0 +1,45 @@ +require 'rails_helper' + +RSpec.describe Registrar::DomainListCSVPresenter do + let(:domain) { instance_spy(DomainPresenter) } + let(:csv) { CSV.parse(described_class.new(domains: [domain], view: view).to_s, converters: :all) } + + describe 'header' do + subject(:header) { csv.first } + + it 'is present' do + columns = [] + columns[0] = 'Domain' + columns[1] = 'Registrant name' + columns[2] = 'Registrant code' + columns[3] = 'Date of expiry' + columns + + expect(header).to eq(columns) + end + end + + describe 'row' do + subject(:row) { csv.second } + + it 'has domain name' do + expect(domain).to receive(:name).and_return('test name') + expect(row[0]).to eq('test name') + end + + it 'has registrant name' do + expect(domain).to receive(:registrant_name).and_return('test registrant name') + expect(row[1]).to eq('test registrant name') + end + + it 'has registrant code' do + expect(domain).to receive(:registrant_code).and_return('test registrant code') + expect(row[2]).to eq('test registrant code') + end + + it 'has expire date' do + expect(domain).to receive(:expire_date).and_return('expire date') + expect(row[3]).to eq('expire date') + end + end +end diff --git a/spec/requests/registrar/domains_controller_spec.rb b/spec/requests/registrar/domains_controller_spec.rb new file mode 100644 index 000000000..630703c6b --- /dev/null +++ b/spec/requests/registrar/domains_controller_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe Registrar::DomainsController, db: true do + describe '#index' do + before do + sign_in_to_registrar_area + end + + it 'responds with success' do + csv_presenter = instance_double(Registrar::DomainListCSVPresenter, to_s: 'csv') + expect(Registrar::DomainListCSVPresenter).to receive(:new).and_return(csv_presenter) + + get registrar_domains_url(format: 'csv') + + expect(response.body).to eq('csv') + end + + it 'returns csv' do + get registrar_domains_url(format: 'csv') + + expect(response).to have_http_status(:success) + end + end + + def sign_in_to_registrar_area(user: FactoryGirl.create(:api_user)) + post registrar_sessions_path, { depp_user: { tag: user.username, password: user.password } } + end +end diff --git a/spec/routing/registrar/domains_routing_spec.rb b/spec/routing/registrar/domains_routing_spec.rb new file mode 100644 index 000000000..e30d1dd24 --- /dev/null +++ b/spec/routing/registrar/domains_routing_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +RSpec.describe Registrar::DomainsController do + describe 'routing' do + it 'routes to #index' do + expect(get: '/registrar/domains').to route_to('registrar/domains#index') + end + end +end