From a9b942dac02247de27ff82152753f4ca0b8ed5a3 Mon Sep 17 00:00:00 2001 From: dinsmol Date: Mon, 24 Jan 2022 23:29:18 +0300 Subject: [PATCH 01/19] Fix domain history csv --- .../admin/domain_versions_controller.rb | 12 ++++++ app/helpers/object_versions_helper.rb | 38 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/app/controllers/admin/domain_versions_controller.rb b/app/controllers/admin/domain_versions_controller.rb index c6bba6d51..8cc69d619 100644 --- a/app/controllers/admin/domain_versions_controller.rb +++ b/app/controllers/admin/domain_versions_controller.rb @@ -88,5 +88,17 @@ module Admin params_copy end + + def render_by_format(page, filename) + respond_to do |format| + format.html { render page } + format.csv do + raw_csv = csv_generate + send_data raw_csv, + filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", + type: "#{Mime[:csv]}; charset=utf-8" + end + end + end end end diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb index dae357cf6..d4baadd45 100644 --- a/app/helpers/object_versions_helper.rb +++ b/app/helpers/object_versions_helper.rb @@ -1,4 +1,6 @@ module ObjectVersionsHelper + CSV_HEADER = ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze + def attach_existing_fields(version, new_object) version.object_changes.to_h.each do |key, value| method_name = "#{key}=".to_sym @@ -11,9 +13,45 @@ module ObjectVersionsHelper version.object.to_h.select { |key, _value| field_names.include?(key) } end + def csv_generate + CSV.generate do |csv| + csv << CSV_HEADER + @versions.each do |version| + attributes = only_present_fields(version, Domain) + domain = Domain.new(attributes) + attach_existing_fields(version, domain) unless version.event == 'destroy' + + csv << create_row(domain, version) + end + end + end + private def event_value(version, val) version.event == 'destroy' ? val.first : val.last end + + def registrant_name(domain, version) + if domain.registrant + domain.registrant.name + else + contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first + if contact.nil? && ver = Version::ContactVersion.where(item_id: domain.registrant_id).last + merged_obj = ver.object_changes.to_h.each_with_object({}) {|(k,v), o| o[k] = v.last } + result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) + contact = Contact.new(result) + end + contact.try(:name) || 'Deleted' + end + end + + def create_row(domain, version) + name = domain.name + registrant = registrant_name(domain, version) + registrar = domain.registrar + event = version.event + created_at = version.created_at.to_formatted_s(:db) + [name, registrant, registrar, event, created_at] + end end From 578b75da2014a72242a94e6b1c45e15b0ab9e6f8 Mon Sep 17 00:00:00 2001 From: dinsmol Date: Tue, 25 Jan 2022 01:08:01 +0300 Subject: [PATCH 02/19] Fix contact history csv --- .../admin/contact_versions_controller.rb | 18 +++++++++ .../admin/domain_versions_controller.rb | 5 ++- app/helpers/object_versions_helper.rb | 38 ++++++++++++++----- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin/contact_versions_controller.rb b/app/controllers/admin/contact_versions_controller.rb index 8ded131c0..2bfb6dbff 100644 --- a/app/controllers/admin/contact_versions_controller.rb +++ b/app/controllers/admin/contact_versions_controller.rb @@ -1,9 +1,13 @@ module Admin class ContactVersionsController < BaseController + include ApplicationHelper include ObjectVersionsHelper load_and_authorize_resource class: Version::ContactVersion + MODEL = Contact + CSV_HEADER = ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'].freeze + def index params[:q] ||= {} @@ -56,5 +60,19 @@ module Admin def create_where_string(key, value) " AND object->>'#{key}' ~* '#{value}'" end + + private + + def render_by_format(page, filename) + respond_to do |format| + format.html { render page } + format.csv do + raw_csv = csv_generate(MODEL, CSV_HEADER) + send_data raw_csv, + filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", + type: "#{Mime[:csv]}; charset=utf-8" + end + end + end end end diff --git a/app/controllers/admin/domain_versions_controller.rb b/app/controllers/admin/domain_versions_controller.rb index 8cc69d619..7dacecb8f 100644 --- a/app/controllers/admin/domain_versions_controller.rb +++ b/app/controllers/admin/domain_versions_controller.rb @@ -4,6 +4,9 @@ module Admin load_and_authorize_resource class: Version::DomainVersion + MODEL = Domain + CSV_HEADER = ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze + def index params[:q] ||= {} @@ -93,7 +96,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = csv_generate + raw_csv = csv_generate(MODEL, CSV_HEADER) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb index d4baadd45..65b54f71e 100644 --- a/app/helpers/object_versions_helper.rb +++ b/app/helpers/object_versions_helper.rb @@ -13,15 +13,15 @@ module ObjectVersionsHelper version.object.to_h.select { |key, _value| field_names.include?(key) } end - def csv_generate + def csv_generate(model, header) CSV.generate do |csv| - csv << CSV_HEADER + csv << header @versions.each do |version| - attributes = only_present_fields(version, Domain) - domain = Domain.new(attributes) - attach_existing_fields(version, domain) unless version.event == 'destroy' + attributes = only_present_fields(version, model) + history_object = model.new(attributes) + attach_existing_fields(version, history_object) unless version.event == 'destroy' - csv << create_row(domain, version) + csv << create_row(history_object, version) end end end @@ -46,10 +46,28 @@ module ObjectVersionsHelper end end - def create_row(domain, version) - name = domain.name - registrant = registrant_name(domain, version) - registrar = domain.registrar + def create_row(history_object, version) + if history_object.is_a?(Domain) + domain_history_row(history_object, version) + else + contact_history_row(history_object, version) + end + end + + def contact_history_row(history_object, version) + name = history_object.name + code = history_object.code + ident = ident_for(history_object) + registrar = history_object.registrar + event = version.event + created_at = version.created_at.to_formatted_s(:db) + [name, code, ident, registrar, event, created_at] + end + + def domain_history_row(history_object, version) + name = history_object.name + registrant = registrant_name(history_object, version) + registrar = history_object.registrar event = version.event created_at = version.created_at.to_formatted_s(:db) [name, registrant, registrar, event, created_at] From b9992177ca5e6c6523aa9cf27e2f2619138daf51 Mon Sep 17 00:00:00 2001 From: dinsmol Date: Tue, 25 Jan 2022 01:14:03 +0300 Subject: [PATCH 03/19] Fix contact history filtration --- app/controllers/admin/contact_versions_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/contact_versions_controller.rb b/app/controllers/admin/contact_versions_controller.rb index 2bfb6dbff..6555f61ac 100644 --- a/app/controllers/admin/contact_versions_controller.rb +++ b/app/controllers/admin/contact_versions_controller.rb @@ -27,7 +27,7 @@ module Admin end versions = Version::ContactVersion.includes(:item).where(where_s).order(created_at: :desc, id: :desc) - @q = versions.ransack(params[:q]) + @q = versions.ransack(fix_date_params) @versions = @q.result.page(params[:page]) @versions = @versions.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? @@ -63,6 +63,15 @@ module Admin private + def fix_date_params + params_copy = params[:q].deep_dup + if params_copy['created_at_lteq'].present? + params_copy['created_at_lteq'] = Date.parse(params_copy['created_at_lteq']) + 1.day + end + + params_copy + end + def render_by_format(page, filename) respond_to do |format| format.html { render page } From 20ace22d678fcd78da43b28ace4adc1673612a94 Mon Sep 17 00:00:00 2001 From: dinsmol Date: Tue, 25 Jan 2022 16:05:56 +0300 Subject: [PATCH 04/19] Fix codeclimate errors --- .../admin/contact_versions_controller.rb | 2 +- .../admin/domain_versions_controller.rb | 2 +- app/helpers/object_versions_helper.rb | 25 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/controllers/admin/contact_versions_controller.rb b/app/controllers/admin/contact_versions_controller.rb index 6555f61ac..b92d8b90b 100644 --- a/app/controllers/admin/contact_versions_controller.rb +++ b/app/controllers/admin/contact_versions_controller.rb @@ -76,7 +76,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER) + raw_csv = csv_generate(MODEL, CSV_HEADER, @versions) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/app/controllers/admin/domain_versions_controller.rb b/app/controllers/admin/domain_versions_controller.rb index 7dacecb8f..d26616375 100644 --- a/app/controllers/admin/domain_versions_controller.rb +++ b/app/controllers/admin/domain_versions_controller.rb @@ -96,7 +96,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER) + raw_csv = csv_generate(MODEL, CSV_HEADER, @versions) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb index 65b54f71e..68185c442 100644 --- a/app/helpers/object_versions_helper.rb +++ b/app/helpers/object_versions_helper.rb @@ -13,10 +13,10 @@ module ObjectVersionsHelper version.object.to_h.select { |key, _value| field_names.include?(key) } end - def csv_generate(model, header) + def csv_generate(model, header, versions) CSV.generate do |csv| csv << header - @versions.each do |version| + versions.each do |version| attributes = only_present_fields(version, model) history_object = model.new(attributes) attach_existing_fields(version, history_object) unless version.event == 'destroy' @@ -33,17 +33,18 @@ module ObjectVersionsHelper end def registrant_name(domain, version) - if domain.registrant - domain.registrant.name - else - contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first - if contact.nil? && ver = Version::ContactVersion.where(item_id: domain.registrant_id).last - merged_obj = ver.object_changes.to_h.each_with_object({}) {|(k,v), o| o[k] = v.last } - result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) - contact = Contact.new(result) - end - contact.try(:name) || 'Deleted' + return domain.registrant.name if domain.registrant + + ver = Version::ContactVersion.where(item_id: domain.registrant_id).last + contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first + + if contact.nil? && ver + merged_obj = ver.object_changes.to_h.transform_values(&:last) + result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) + contact = Contact.new(result) end + + contact.try(:name) || 'Deleted' end def create_row(history_object, version) From b78f3e846d3b836b92ff17f6131c5edf888af13a Mon Sep 17 00:00:00 2001 From: dinsmol Date: Sat, 26 Feb 2022 12:46:23 +0300 Subject: [PATCH 05/19] Fix data for csv --- .../admin/contact_versions_controller.rb | 2 +- .../admin/domain_versions_controller.rb | 2 +- db/structure.sql | 160 ++++++++++++++++-- 3 files changed, 146 insertions(+), 18 deletions(-) diff --git a/app/controllers/admin/contact_versions_controller.rb b/app/controllers/admin/contact_versions_controller.rb index b92d8b90b..534a4192c 100644 --- a/app/controllers/admin/contact_versions_controller.rb +++ b/app/controllers/admin/contact_versions_controller.rb @@ -76,7 +76,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER, @versions) + raw_csv = csv_generate(MODEL, CSV_HEADER, @q.result) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/app/controllers/admin/domain_versions_controller.rb b/app/controllers/admin/domain_versions_controller.rb index d26616375..a7741130f 100644 --- a/app/controllers/admin/domain_versions_controller.rb +++ b/app/controllers/admin/domain_versions_controller.rb @@ -96,7 +96,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER, @versions) + raw_csv = csv_generate(MODEL, CSV_HEADER, @q.result) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/db/structure.sql b/db/structure.sql index 5b842d4a4..0c8420f43 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -51,6 +51,20 @@ CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public; COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs'; +-- +-- Name: pg_stat_statements; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public; + + +-- +-- Name: EXTENSION pg_stat_statements; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION pg_stat_statements IS 'track execution statistics of all SQL statements executed'; + + -- -- Name: pgcrypto; Type: EXTENSION; Schema: -; Owner: - -- @@ -202,6 +216,8 @@ CREATE FUNCTION public.generate_zonefile(i_origin character varying) RETURNS tex SET default_tablespace = ''; +SET default_with_oids = false; + -- -- Name: account_activities; Type: TABLE; Schema: public; Owner: - -- @@ -809,7 +825,9 @@ CREATE TABLE public.dnskeys ( creator_str character varying, updator_str character varying, legacy_domain_id integer, - updated_at timestamp without time zone + updated_at timestamp without time zone, + validation_datetime timestamp without time zone, + failed_validation_reason character varying ); @@ -936,6 +954,7 @@ CREATE TABLE public.domains ( pending_json jsonb, force_delete_date date, statuses character varying[], + status_notes public.hstore, statuses_before_force_delete character varying[] DEFAULT '{}'::character varying[], upid integer, up_date timestamp without time zone, @@ -943,8 +962,7 @@ CREATE TABLE public.domains ( locked_by_registrant_at timestamp without time zone, force_delete_start timestamp without time zone, force_delete_data public.hstore, - json_statuses_history jsonb, - status_notes public.hstore + json_statuses_history jsonb ); @@ -1177,6 +1195,7 @@ CREATE TABLE public.invoices ( buyer_vat_no character varying, issue_date date NOT NULL, e_invoice_sent_at timestamp without time zone, + payment_link character varying, CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date)) ); @@ -2263,6 +2282,74 @@ CREATE SEQUENCE public.payment_orders_id_seq ALTER SEQUENCE public.payment_orders_id_seq OWNED BY public.payment_orders.id; +-- +-- Name: pghero_query_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.pghero_query_stats ( + id bigint NOT NULL, + database text, + "user" text, + query text, + query_hash bigint, + total_time double precision, + calls bigint, + captured_at timestamp without time zone +); + + +-- +-- Name: pghero_query_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.pghero_query_stats_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: pghero_query_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.pghero_query_stats_id_seq OWNED BY public.pghero_query_stats.id; + + +-- +-- Name: pghero_space_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.pghero_space_stats ( + id bigint NOT NULL, + database text, + schema text, + relation text, + size bigint, + captured_at timestamp without time zone +); + + +-- +-- Name: pghero_space_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.pghero_space_stats_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: pghero_space_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.pghero_space_stats_id_seq OWNED BY public.pghero_space_stats.id; + + -- -- Name: prices; Type: TABLE; Schema: public; Owner: - -- @@ -2623,8 +2710,7 @@ CREATE TABLE public.validation_events ( validation_eventable_type character varying, validation_eventable_id bigint, created_at timestamp(6) without time zone NOT NULL, - updated_at timestamp(6) without time zone NOT NULL, - event_type public.validation_type + updated_at timestamp(6) without time zone NOT NULL ); @@ -3166,6 +3252,20 @@ ALTER TABLE ONLY public.notifications ALTER COLUMN id SET DEFAULT nextval('publi ALTER TABLE ONLY public.payment_orders ALTER COLUMN id SET DEFAULT nextval('public.payment_orders_id_seq'::regclass); +-- +-- Name: pghero_query_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_query_stats ALTER COLUMN id SET DEFAULT nextval('public.pghero_query_stats_id_seq'::regclass); + + +-- +-- Name: pghero_space_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_space_stats ALTER COLUMN id SET DEFAULT nextval('public.pghero_space_stats_id_seq'::regclass); + + -- -- Name: prices id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3689,6 +3789,22 @@ ALTER TABLE ONLY public.payment_orders ADD CONSTRAINT payment_orders_pkey PRIMARY KEY (id); +-- +-- Name: pghero_query_stats pghero_query_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_query_stats + ADD CONSTRAINT pghero_query_stats_pkey PRIMARY KEY (id); + + +-- +-- Name: pghero_space_stats pghero_space_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_space_stats + ADD CONSTRAINT pghero_space_stats_pkey PRIMARY KEY (id); + + -- -- Name: prices prices_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -4459,6 +4575,20 @@ CREATE INDEX index_notifications_on_registrar_id ON public.notifications USING b CREATE INDEX index_payment_orders_on_invoice_id ON public.payment_orders USING btree (invoice_id); +-- +-- Name: index_pghero_query_stats_on_database_and_captured_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_pghero_query_stats_on_database_and_captured_at ON public.pghero_query_stats USING btree (database, captured_at); + + +-- +-- Name: index_pghero_space_stats_on_database_and_captured_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_pghero_space_stats_on_database_and_captured_at ON public.pghero_space_stats USING btree (database, captured_at); + + -- -- Name: index_prices_on_zone_id; Type: INDEX; Schema: public; Owner: - -- @@ -4515,13 +4645,6 @@ CREATE INDEX index_users_on_registrar_id ON public.users USING btree (registrar_ CREATE INDEX index_validation_events_on_event_data ON public.validation_events USING gin (event_data); --- --- Name: index_validation_events_on_event_type; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_validation_events_on_event_type ON public.validation_events USING btree (event_type); - - -- -- Name: index_validation_events_on_validation_eventable; Type: INDEX; Schema: public; Owner: - -- @@ -5267,15 +5390,20 @@ INSERT INTO "schema_migrations" (version) VALUES ('20210708131814'), ('20210729131100'), ('20210729134625'), -('20210827185249'), -('20211029073644'), +('20211028122103'), +('20211028125245'), +('20211029082225'), ('20211124071418'), +('20211124084308'), ('20211125181033'), ('20211125184334'), ('20211126085139'), +('20211231113934'), ('20220106123143'), ('20220113201642'), -('20220113220809'); - +('20220113220809'), +('20220124105717'), +('20220216113112'), +('20220228093211'); From 71001ce05639dfca185f8fb60a09a8cba8d4413c Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Tue, 8 Mar 2022 17:31:00 +0200 Subject: [PATCH 06/19] Add file fixture to download history tests --- test/fixtures/files/contact_versions.csv | 3 +++ test/fixtures/files/domain_versions.csv | 3 +++ test/system/admin_area/contact_versions_test.rb | 3 +-- test/system/admin_area/domain_versions_test.rb | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/files/contact_versions.csv create mode 100644 test/fixtures/files/domain_versions.csv diff --git a/test/fixtures/files/contact_versions.csv b/test/fixtures/files/contact_versions.csv new file mode 100644 index 000000000..c794026c2 --- /dev/null +++ b/test/fixtures/files/contact_versions.csv @@ -0,0 +1,3 @@ +Name,ID,Ident,Registrar,Action,Created at +,test_code,[ ],Best Names,update,2018-04-23 15:50:48 +,,[ ],,update,2010-07-04 21:00:00 diff --git a/test/fixtures/files/domain_versions.csv b/test/fixtures/files/domain_versions.csv new file mode 100644 index 000000000..8fa7fa9fe --- /dev/null +++ b/test/fixtures/files/domain_versions.csv @@ -0,0 +1,3 @@ +Name,Registrant,Registrar,Action,Created at +,test_code,Best Names,update,2018-04-23 15:50:48 +,John,,update,2010-07-04 21:00:00 diff --git a/test/system/admin_area/contact_versions_test.rb b/test/system/admin_area/contact_versions_test.rb index f040646bb..e199f5768 100644 --- a/test/system/admin_area/contact_versions_test.rb +++ b/test/system/admin_area/contact_versions_test.rb @@ -62,11 +62,10 @@ class ContactVersionsTest < ApplicationSystemTestCase travel_to now get admin_contact_versions_path(format: :csv) - assert_response :ok assert_equal 'text/csv; charset=utf-8', response.headers['Content-Type'] assert_equal %(attachment; filename="contact_history_#{Time.zone.now.to_formatted_s(:number)}.csv"; filename*=UTF-8''contact_history_#{Time.zone.now.to_formatted_s(:number)}.csv), response.headers['Content-Disposition'] - assert_not_empty response.body + assert_equal file_fixture('contact_versions.csv').read, response.body end end diff --git a/test/system/admin_area/domain_versions_test.rb b/test/system/admin_area/domain_versions_test.rb index a8aeb0cd4..75b66b1bb 100644 --- a/test/system/admin_area/domain_versions_test.rb +++ b/test/system/admin_area/domain_versions_test.rb @@ -98,7 +98,7 @@ class DomainVersionsTest < ApplicationSystemTestCase assert_equal 'text/csv; charset=utf-8', response.headers['Content-Type'] assert_equal %(attachment; filename="domain_history_#{Time.zone.now.to_formatted_s(:number)}.csv"; filename*=UTF-8''domain_history_#{Time.zone.now.to_formatted_s(:number)}.csv), response.headers['Content-Disposition'] - assert_not_empty response.body + assert_equal file_fixture('domain_versions.csv').read, response.body end def test_search_event_param From 807419bc3a628116f55c15119db331b688623490 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Wed, 9 Mar 2022 15:37:30 +0200 Subject: [PATCH 07/19] Tests for domains csv download at admin --- test/fixtures/files/domains.csv | 2 ++ test/system/admin_area/domains/csv_test.rb | 10 +++------- 2 files changed, 5 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/files/domains.csv diff --git a/test/fixtures/files/domains.csv b/test/fixtures/files/domains.csv new file mode 100644 index 000000000..10a6e2b65 --- /dev/null +++ b/test/fixtures/files/domains.csv @@ -0,0 +1,2 @@ +Domain,Registrant,Valid to,Registrar,Created at,Statuses,Contacts code,Force delete date,Force delete data +hospital.test,Thiago,05/07/2010 03:00,Good Names,05/07/2009 03:00,[],[john-001, william-001, william-001],08/03/2022 00:00, diff --git a/test/system/admin_area/domains/csv_test.rb b/test/system/admin_area/domains/csv_test.rb index c84e2cf0e..cae01b884 100644 --- a/test/system/admin_area/domains/csv_test.rb +++ b/test/system/admin_area/domains/csv_test.rb @@ -1,18 +1,14 @@ require 'application_system_test_case' class AdminAreaCsvTest < ApplicationSystemTestCase - setup do - sign_in users(:admin) - end + setup { sign_in users(:admin) } def test_downloads_domain_list_as_csv - search_params = {"valid_to_lteq"=>nil} - expected_csv = Domain.includes(:registrar, :registrant).search(search_params).result.to_csv - travel_to Time.zone.parse('2010-07-05 10:30') visit admin_domains_url click_link('CSV') + assert_equal "attachment; filename=\"domains_#{Time.zone.now.to_formatted_s(:number)}.csv\"; filename*=UTF-8''domains_#{Time.zone.now.to_formatted_s(:number)}.csv", response_headers['Content-Disposition'] - assert_equal expected_csv, page.body + assert_equal file_fixture('domains.csv').read, page.body end end From 9fb4a6d7e6b19f7ba8647b69f0cd378d7a663a52 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Thu, 10 Mar 2022 16:03:53 +0200 Subject: [PATCH 08/19] Refactor `admin/contact_version` and `admin/domain_version` csv generation logic --- app/controllers/admin/base_controller.rb | 2 +- .../admin/contact_versions_controller.rb | 16 ---- .../admin/domain_versions_controller.rb | 22 +----- app/helpers/application_helper.rb | 24 ------ app/helpers/object_versions_helper.rb | 76 ------------------- app/models/contact.rb | 7 ++ app/models/version/contact_version.rb | 17 +++++ app/models/version/domain_version.rb | 33 ++++++++ app/services/csv_generator.rb | 17 +++++ app/services/object_versions_parser.rb | 28 +++++++ app/views/admin/contact_versions/index.haml | 6 +- app/views/admin/contact_versions/show.haml | 7 +- app/views/admin/contacts/index.haml | 2 +- .../admin/contacts/partials/_general.haml | 2 +- app/views/admin/domain_versions/archive.haml | 4 +- app/views/admin/domain_versions/show.haml | 4 +- app/views/registrar/contacts/index.html.erb | 2 +- .../registrar/contacts/list_pdf.html.erb | 2 +- .../registrar/contacts/partials/_general.haml | 2 +- 19 files changed, 117 insertions(+), 156 deletions(-) delete mode 100644 app/helpers/object_versions_helper.rb create mode 100644 app/services/csv_generator.rb create mode 100644 app/services/object_versions_parser.rb diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 016c0a750..56806ba3e 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -26,7 +26,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = @q.result.to_csv + raw_csv = CsvGenerator.generate_csv(@q.result) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/app/controllers/admin/contact_versions_controller.rb b/app/controllers/admin/contact_versions_controller.rb index 534a4192c..2a26035c9 100644 --- a/app/controllers/admin/contact_versions_controller.rb +++ b/app/controllers/admin/contact_versions_controller.rb @@ -1,13 +1,9 @@ module Admin class ContactVersionsController < BaseController include ApplicationHelper - include ObjectVersionsHelper load_and_authorize_resource class: Version::ContactVersion - MODEL = Contact - CSV_HEADER = ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'].freeze - def index params[:q] ||= {} @@ -71,17 +67,5 @@ module Admin params_copy end - - def render_by_format(page, filename) - respond_to do |format| - format.html { render page } - format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER, @q.result) - send_data raw_csv, - filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", - type: "#{Mime[:csv]}; charset=utf-8" - end - end - end end end diff --git a/app/controllers/admin/domain_versions_controller.rb b/app/controllers/admin/domain_versions_controller.rb index a7741130f..c82347ff9 100644 --- a/app/controllers/admin/domain_versions_controller.rb +++ b/app/controllers/admin/domain_versions_controller.rb @@ -1,12 +1,7 @@ module Admin class DomainVersionsController < BaseController - include ObjectVersionsHelper - load_and_authorize_resource class: Version::DomainVersion - MODEL = Domain - CSV_HEADER = ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze - def index params[:q] ||= {} @@ -85,23 +80,10 @@ module Admin def fix_date_params params_copy = params[:q].deep_dup - if params_copy['created_at_lteq'].present? - params_copy['created_at_lteq'] = Date.parse(params_copy['created_at_lteq']) + 1.day - end + created_at = params_copy['created_at_lteq'] + params_copy['created_at_lteq'] = Date.parse(created_at) + 1.day if created_at.present? params_copy end - - def render_by_format(page, filename) - respond_to do |format| - format.html { render page } - format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER, @q.result) - send_data raw_csv, - filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", - type: "#{Mime[:csv]}; charset=utf-8" - end - end - end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 3de98b88c..6829040c2 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -9,30 +9,6 @@ module ApplicationHelper "background-image: url(#{image_path("#{unstable_env}.png")});" end - def ident_for(contact) - if contact.is_a? Hash - ident_country_code = contact[:ident_country_code] - ident_type = contact[:ident_type] - ident = contact[:ident] - else - ident_country_code = contact.ident_country_code - ident_type = contact.ident_type - ident = contact.ident - end - - case ident_type - when 'birthday' - "#{ident} [#{ident_country_code} #{ident_type}]" - else - if ident.present? - "#{ident} [#{ident_country_code} #{ident_type}]" - else - "[#{ident_country_code} #{ident_type}]" - end - - end - end - def current_commit_link hash = `git rev-parse --short HEAD` current_repo = `git remote get-url origin`.gsub('com:', 'com/') diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb deleted file mode 100644 index 68185c442..000000000 --- a/app/helpers/object_versions_helper.rb +++ /dev/null @@ -1,76 +0,0 @@ -module ObjectVersionsHelper - CSV_HEADER = ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze - - def attach_existing_fields(version, new_object) - version.object_changes.to_h.each do |key, value| - method_name = "#{key}=".to_sym - new_object.public_send(method_name, event_value(version, value)) if new_object.respond_to?(method_name) - end - end - - def only_present_fields(version, model) - field_names = model.column_names - version.object.to_h.select { |key, _value| field_names.include?(key) } - end - - def csv_generate(model, header, versions) - CSV.generate do |csv| - csv << header - versions.each do |version| - attributes = only_present_fields(version, model) - history_object = model.new(attributes) - attach_existing_fields(version, history_object) unless version.event == 'destroy' - - csv << create_row(history_object, version) - end - end - end - - private - - def event_value(version, val) - version.event == 'destroy' ? val.first : val.last - end - - def registrant_name(domain, version) - return domain.registrant.name if domain.registrant - - ver = Version::ContactVersion.where(item_id: domain.registrant_id).last - contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first - - if contact.nil? && ver - merged_obj = ver.object_changes.to_h.transform_values(&:last) - result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) - contact = Contact.new(result) - end - - contact.try(:name) || 'Deleted' - end - - def create_row(history_object, version) - if history_object.is_a?(Domain) - domain_history_row(history_object, version) - else - contact_history_row(history_object, version) - end - end - - def contact_history_row(history_object, version) - name = history_object.name - code = history_object.code - ident = ident_for(history_object) - registrar = history_object.registrar - event = version.event - created_at = version.created_at.to_formatted_s(:db) - [name, code, ident, registrar, event, created_at] - end - - def domain_history_row(history_object, version) - name = history_object.name - registrant = registrant_name(history_object, version) - registrar = history_object.registrar - event = version.event - created_at = version.created_at.to_formatted_s(:db) - [name, registrant, registrar, event, created_at] - end -end diff --git a/app/models/contact.rb b/app/models/contact.rb index 84d4ba962..f15637f6f 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -569,4 +569,11 @@ class Contact < ApplicationRecord def deletable? !linked? end + + def ident_human_description + description = "[#{ident_country_code} #{ident_type}]" + description.prepend("#{ident} ") if ident.present? + + description + end end diff --git a/app/models/version/contact_version.rb b/app/models/version/contact_version.rb index 95bd4b677..498e6d468 100644 --- a/app/models/version/contact_version.rb +++ b/app/models/version/contact_version.rb @@ -4,4 +4,21 @@ class Version::ContactVersion < PaperTrail::Version self.table_name = :log_contacts self.sequence_name = :log_contacts_id_seq + + def as_csv_row + contact = ObjectVersionsParser.new(self).parse + + [ + contact.name, + contact.code, + contact.ident_human_description, + contact.registrar, + event, + created_at.to_formatted_s(:db) + ] + end + + def self.csv_header + ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'].freeze + end end diff --git a/app/models/version/domain_version.rb b/app/models/version/domain_version.rb index 2c6848d4b..240adc866 100644 --- a/app/models/version/domain_version.rb +++ b/app/models/version/domain_version.rb @@ -7,6 +7,18 @@ class Version::DomainVersion < PaperTrail::Version scope :deleted, -> { where(event: 'destroy') } + def as_csv_row + domain = ObjectVersionsParser.new(self).parse + + [ + domain.name, + registrant_name(domain), + domain.registrar, + event, + created_at.to_formatted_s(:db) + ] + end + def self.was_contact_linked?(contact_id) sql = <<-SQL SELECT @@ -43,4 +55,25 @@ class Version::DomainVersion < PaperTrail::Version count_by_sql(sql).nonzero? end + + def self.csv_header + ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze + end + + private + + def registrant_name(domain) + return domain.registrant.name if domain.registrant + + ver = Version::ContactVersion.where(item_id: domain.registrant_id).last + contact = Contact.all_versions_for([domain.registrant_id], created_at).first + + if contact.nil? && ver + merged_obj = ver.object_changes.to_h.transform_values(&:last) + result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) + contact = Contact.new(result) + end + + contact.try(:name) || 'Deleted' + end end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb new file mode 100644 index 000000000..43c116b7e --- /dev/null +++ b/app/services/csv_generator.rb @@ -0,0 +1,17 @@ +class CsvGenerator + def self.generate_csv(objects) + class_name = objects.first.class + return objects.to_csv unless custom_csv(class_name) + + CSV.generate do |csv| + csv << class_name.csv_header + objects.each { |object| csv << object.as_csv_row } + end + end + + private + + def self.custom_csv(class_name) + [Version::DomainVersion, Version::ContactVersion].include?(class_name) + end +end diff --git a/app/services/object_versions_parser.rb b/app/services/object_versions_parser.rb new file mode 100644 index 000000000..5871a6bd6 --- /dev/null +++ b/app/services/object_versions_parser.rb @@ -0,0 +1,28 @@ +class ObjectVersionsParser + def initialize(version) + @version = version + end + + def parse + model = @version.item_type.constantize + attributes = only_present_fields(model) + history_object = model.new(attributes) + attach_existing_fields(history_object) unless @version.event == 'destroy' + + history_object + end + + private + + def attach_existing_fields(history_object) + @version.object_changes.to_h.each do |key, value| + method_name = "#{key}=".to_sym + history_object.public_send(method_name, value.last) if history_object.respond_to?(method_name) + end + end + + def only_present_fields(model) + field_names = model.column_names + @version.object.to_h.select { |key, _value| field_names.include?(key) } + end +end diff --git a/app/views/admin/contact_versions/index.haml b/app/views/admin/contact_versions/index.haml index 4d7a9948d..97c267d30 100644 --- a/app/views/admin/contact_versions/index.haml +++ b/app/views/admin/contact_versions/index.haml @@ -64,14 +64,12 @@ %tbody - @versions.each do |version| - if version - - attributes = only_present_fields(version, Contact) - - contact = Contact.new(attributes) - - attach_existing_fields(version, contact) + - contact = ObjectVersionsParser.new(version).parse %tr %td= link_to(contact.name, admin_contact_version_path(version.id)) %td= contact.code - %td= ident_for(contact) + %td= contact.ident_human_description %td - if contact.registrar = link_to(contact.registrar, admin_registrar_path(contact.registrar)) diff --git a/app/views/admin/contact_versions/show.haml b/app/views/admin/contact_versions/show.haml index 901f5ee1a..57c8c3ccc 100644 --- a/app/views/admin/contact_versions/show.haml +++ b/app/views/admin/contact_versions/show.haml @@ -1,6 +1,5 @@ -- attributes = only_present_fields(@version, Contact) -- contact = Contact.new(attributes) -- attach_existing_fields(@version, contact) +- contact = ObjectVersionsParser.new(@version).parse + = render 'shared/title', name: contact.name .row @@ -23,7 +22,7 @@ %dt= t(:ident) %dd{class: changing_css_class(@version,"ident_country_code", "ident_type", "ident")} - = ident_for(contact) + = contact.ident_human_description - if contact.email.present? %dt= t(:email) diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml index 0812913a1..b4198b8cc 100644 --- a/app/views/admin/contacts/index.haml +++ b/app/views/admin/contacts/index.haml @@ -100,7 +100,7 @@ %tr %td= link_to(contact, admin_contact_path(contact)) %td= contact.code - %td= ident_for(contact) + %td= contact.ident_human_description %td= contact.email %td= l(contact.created_at, format: :short) %td diff --git a/app/views/admin/contacts/partials/_general.haml b/app/views/admin/contacts/partials/_general.haml index 2396861fb..4b8d4ec32 100644 --- a/app/views/admin/contacts/partials/_general.haml +++ b/app/views/admin/contacts/partials/_general.haml @@ -14,7 +14,7 @@ %br %dt.left_25= t(:ident) - %dd.left_25= ident_for(@contact) + %dd.left_25= @contact.ident_human_description %dt.left_25= t(:email) %dd.left_25= @contact.email diff --git a/app/views/admin/domain_versions/archive.haml b/app/views/admin/domain_versions/archive.haml index ec2034ed1..85105b9f0 100644 --- a/app/views/admin/domain_versions/archive.haml +++ b/app/views/admin/domain_versions/archive.haml @@ -62,9 +62,7 @@ %tbody - @versions.each do |version| - if version - - attributes = only_present_fields(version, Domain) - - domain = Domain.new(attributes) - - attach_existing_fields(version, domain) unless version.event == 'destroy' + - domain = ObjectVersionsParser.new(version).parse %tr %td= link_to(domain.name, admin_domain_version_path(version.id)) diff --git a/app/views/admin/domain_versions/show.haml b/app/views/admin/domain_versions/show.haml index 11f70599f..ab49dffee 100644 --- a/app/views/admin/domain_versions/show.haml +++ b/app/views/admin/domain_versions/show.haml @@ -1,6 +1,4 @@ -- present_fields = only_present_fields(@version, Domain) -- domain = Domain.new(present_fields) -- attach_existing_fields(@version, domain) unless @version.event == 'destroy' +- domain = ObjectVersionsParser.new(@version).parse - if @version - children = HashWithIndifferentAccess.new(@version.children) diff --git a/app/views/registrar/contacts/index.html.erb b/app/views/registrar/contacts/index.html.erb index 4a7e8759a..35683360e 100644 --- a/app/views/registrar/contacts/index.html.erb +++ b/app/views/registrar/contacts/index.html.erb @@ -44,7 +44,7 @@ <%= contact.code %> - <%= ident_for(contact) %> + <%= contact.ident_human_description %> <%= l(contact.created_at, format: :short) %> diff --git a/app/views/registrar/contacts/list_pdf.html.erb b/app/views/registrar/contacts/list_pdf.html.erb index b9bbb1c0e..52e5956dd 100644 --- a/app/views/registrar/contacts/list_pdf.html.erb +++ b/app/views/registrar/contacts/list_pdf.html.erb @@ -20,7 +20,7 @@ <%= contact %> <%= contact.code %> - <%= ident_for(contact) %> + <%= contact.ident_human_description %> <%= l(contact.created_at, format: :short) %> <%= contact.registrar %> diff --git a/app/views/registrar/contacts/partials/_general.haml b/app/views/registrar/contacts/partials/_general.haml index 5fc8ec027..4e2a92621 100644 --- a/app/views/registrar/contacts/partials/_general.haml +++ b/app/views/registrar/contacts/partials/_general.haml @@ -14,7 +14,7 @@ %br %dt= t(:ident) - %dd= ident_for(@contact) + %dd= @contact.ident_human_description %dt= t(:email) %dd= @contact.email From 6263ded68ff1d3fbc4116a876b628b1d0971b9f2 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Fri, 11 Mar 2022 14:37:46 +0200 Subject: [PATCH 09/19] Fix admin domains CSV output --- app/models/domain.rb | 29 ++++++++++++++++++++++ app/models/version/domain_version.rb | 19 +------------- app/services/csv_generator.rb | 2 +- test/fixtures/files/domains.csv | 9 +++++-- test/system/admin_area/domains/csv_test.rb | 5 ++++ 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 873216cf1..2f084ed4d 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -753,6 +753,35 @@ class Domain < ApplicationRecord contacts.select(&:email_verification_failed?)&.map(&:email)&.uniq end + def as_csv_row + [ + name, + registrant_name, + valid_to.to_formatted_s(:db), + registrar, + created_at.to_formatted_s(:db), + statuses, + contacts.pluck(:code), + force_delete_date, + force_delete_data + ] + end + + def registrant_name + return registrant.name if registrant + + ver = Version::ContactVersion.where(item_id: registrant_id).last + contact = Contact.all_versions_for([registrant_id], created_at).first + + contact = ObjectVersionsParser.new(ver).parse if contact.nil? && ver + + contact.try(:name) || 'Deleted' + end + + def self.csv_header + ['Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data'].freeze + end + def self.pdf(html) kit = PDFKit.new(html) kit.to_pdf diff --git a/app/models/version/domain_version.rb b/app/models/version/domain_version.rb index 240adc866..52b10fc53 100644 --- a/app/models/version/domain_version.rb +++ b/app/models/version/domain_version.rb @@ -12,7 +12,7 @@ class Version::DomainVersion < PaperTrail::Version [ domain.name, - registrant_name(domain), + domain.registrant_name, domain.registrar, event, created_at.to_formatted_s(:db) @@ -59,21 +59,4 @@ class Version::DomainVersion < PaperTrail::Version def self.csv_header ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze end - - private - - def registrant_name(domain) - return domain.registrant.name if domain.registrant - - ver = Version::ContactVersion.where(item_id: domain.registrant_id).last - contact = Contact.all_versions_for([domain.registrant_id], created_at).first - - if contact.nil? && ver - merged_obj = ver.object_changes.to_h.transform_values(&:last) - result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) - contact = Contact.new(result) - end - - contact.try(:name) || 'Deleted' - end end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb index 43c116b7e..c0d21ad62 100644 --- a/app/services/csv_generator.rb +++ b/app/services/csv_generator.rb @@ -12,6 +12,6 @@ class CsvGenerator private def self.custom_csv(class_name) - [Version::DomainVersion, Version::ContactVersion].include?(class_name) + [Version::DomainVersion, Version::ContactVersion, Domain].include?(class_name) end end diff --git a/test/fixtures/files/domains.csv b/test/fixtures/files/domains.csv index 10a6e2b65..69e9df8a8 100644 --- a/test/fixtures/files/domains.csv +++ b/test/fixtures/files/domains.csv @@ -1,2 +1,7 @@ -Domain,Registrant,Valid to,Registrar,Created at,Statuses,Contacts code,Force delete date,Force delete data -hospital.test,Thiago,05/07/2010 03:00,Good Names,05/07/2009 03:00,[],[john-001, william-001, william-001],08/03/2022 00:00, +Domain,Registrant,Valid to,Registrar,Created at,Statuses,Contacts code,Force delete date,Force delete data +shop.test,John,2010-07-04 21:00:00,Best Names,2010-07-05 07:30:00,"[""ok""]","[""william-001"", ""jane-001"", ""acme-ltd-001""]",2010-07-08, +airport.test,John,2010-07-05 00:00:00,Best Names,2010-07-05 07:30:00,"[""ok""]","[""john-001"", ""william-001"", ""william-001""]",, +library.test,Acme Ltd,2010-07-05 00:00:00,Best Names,2010-07-05 07:30:00,"[""inactive""]","[""john-001"", ""acme-ltd-001""]",, +metro.test,Jack,2010-07-05 00:00:00,Good Names,2010-07-05 07:30:00,[],"[""jack-001"", ""jack-001""]",, +hospital.test,John,2010-07-05 00:00:00,Good Names,2010-07-05 07:30:00,"[""inactive""]","[""john-001"", ""john-001""]",, +invalid.test,any,2010-07-04 21:00:00,Best Names,2010-07-05 07:30:00,"[""inactive""]","[""invalid"", ""invalid""]",, diff --git a/test/system/admin_area/domains/csv_test.rb b/test/system/admin_area/domains/csv_test.rb index cae01b884..296117cf8 100644 --- a/test/system/admin_area/domains/csv_test.rb +++ b/test/system/admin_area/domains/csv_test.rb @@ -5,6 +5,11 @@ class AdminAreaCsvTest < ApplicationSystemTestCase def test_downloads_domain_list_as_csv travel_to Time.zone.parse('2010-07-05 10:30') + Domain.all.each do |domain| + domain.created_at = Time.zone.now + domain.save(:validate => false) + end + visit admin_domains_url click_link('CSV') From f44bdd1930888fbd924696187e41281f71ce7125 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Mon, 14 Mar 2022 09:22:03 +0200 Subject: [PATCH 10/19] Fix admin contacts CSV output --- app/models/contact.rb | 16 ++++++++++++++++ app/services/csv_generator.rb | 2 +- test/fixtures/files/contacts.csv | 10 ++++++++++ test/system/admin_area/contacts/csv_test.rb | 19 +++++++++++++++++++ test/system/admin_area/domains/csv_test.rb | 4 ++-- 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/files/contacts.csv create mode 100644 test/system/admin_area/contacts/csv_test.rb diff --git a/app/models/contact.rb b/app/models/contact.rb index f15637f6f..367777efb 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -576,4 +576,20 @@ class Contact < ApplicationRecord description end + + def as_csv_row + [ + name, + code, + ident_human_description, + email, + created_at.to_formatted_s(:db), + registrar, + phone, + ] + end + + def self.csv_header + ['Name', 'ID', 'Ident', 'E-mail', 'Created at', 'Registrar', 'Phone'].freeze + end end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb index c0d21ad62..122a04ff5 100644 --- a/app/services/csv_generator.rb +++ b/app/services/csv_generator.rb @@ -12,6 +12,6 @@ class CsvGenerator private def self.custom_csv(class_name) - [Version::DomainVersion, Version::ContactVersion, Domain].include?(class_name) + [Version::DomainVersion, Version::ContactVersion, Domain, Contact, Invoice].include?(class_name) end end diff --git a/test/fixtures/files/contacts.csv b/test/fixtures/files/contacts.csv new file mode 100644 index 000000000..73d9104af --- /dev/null +++ b/test/fixtures/files/contacts.csv @@ -0,0 +1,10 @@ +Name,ID,Ident,E-mail,Created at,Registrar,Phone +John,john-001,1234 [US priv],john@inbox.test,2010-07-05 07:30:00,Best Names,+555.555 +William,william-001,12345 [US priv],william@inbox.test,2010-07-05 07:30:00,Best Names,+555.555 +Jane,jane-001,123456 [US priv],jane@mail.test,2010-07-05 07:30:00,Best Names,+555.555 +Acme Ltd,acme-ltd-001,1234567 [US org],acme@outlook.test,2010-07-05 07:30:00,Best Names,+555.555 +Jack,jack-001,12345678 [US org],jack@inbox.test,2010-07-05 07:30:00,Good Names,+555.555 +William,william-002,12345 [US priv],william@inbox.test,2010-07-05 07:30:00,Good Names,+555.555 +Registrar Ltd,registrarltd-001,1234567890 [US org],registrar@inbox.test,2010-07-05 07:30:00,Good Names,+555.555 +any,invalid,[ ],invalid@invalid.test,2010-07-05 07:30:00,Best Names, +any,invalid_email,[ ],invalid@invalid.,2010-07-05 07:30:00,Best Names, diff --git a/test/system/admin_area/contacts/csv_test.rb b/test/system/admin_area/contacts/csv_test.rb new file mode 100644 index 000000000..552bcf437 --- /dev/null +++ b/test/system/admin_area/contacts/csv_test.rb @@ -0,0 +1,19 @@ +require 'application_system_test_case' + +class ContactsCsvTest < ApplicationSystemTestCase + setup { sign_in users(:admin) } + + def test_download_contacts_list_as_csv + travel_to Time.zone.parse('2010-07-05 10:30') + Contact.all.each do |contact| + contact.created_at = Time.zone.now + contact.save(:validate => false) + end + + visit admin_contacts_url + click_link('CSV') + + assert_equal "attachment; filename=\"contacts_#{Time.zone.now.to_formatted_s(:number)}.csv\"; filename*=UTF-8''contacts_#{Time.zone.now.to_formatted_s(:number)}.csv", response_headers['Content-Disposition'] + assert_equal file_fixture('contacts.csv').read, page.body + end +end diff --git a/test/system/admin_area/domains/csv_test.rb b/test/system/admin_area/domains/csv_test.rb index 296117cf8..568815dd7 100644 --- a/test/system/admin_area/domains/csv_test.rb +++ b/test/system/admin_area/domains/csv_test.rb @@ -1,9 +1,9 @@ require 'application_system_test_case' -class AdminAreaCsvTest < ApplicationSystemTestCase +class DomainsCsvTest < ApplicationSystemTestCase setup { sign_in users(:admin) } - def test_downloads_domain_list_as_csv + def test_download_domains_list_as_csv travel_to Time.zone.parse('2010-07-05 10:30') Domain.all.each do |domain| domain.created_at = Time.zone.now From 7d79e6528d3208e3dc8adb7b8f375ee75645393e Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Mon, 14 Mar 2022 12:09:13 +0200 Subject: [PATCH 11/19] Fix admin invoices CSV output --- app/models/invoice.rb | 27 +++++++++++++++++++++++++ app/services/csv_generator.rb | 2 +- test/fixtures/files/invoices.csv | 3 +++ test/system/admin_area/invoices_test.rb | 10 +++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/files/invoices.csv diff --git a/app/models/invoice.rb b/app/models/invoice.rb index df8b7aff8..d0a1950a5 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -117,6 +117,23 @@ class Invoice < ApplicationRecord e_invoice_sent_at.present? end + def as_csv_row + [ + number, + buyer, + cancelled? ? I18n.t(:cancelled) : due_date, + receipt_date_status, + issue_date, + total, + currency, + seller_name + ] + end + + def self.csv_header + ['Number', 'Buyer', 'Due Date', 'Receipt Date', 'Issue Date', 'Total', 'Currency', 'Seller Name'].freeze + end + def self.create_from_transaction!(transaction) registrar_user = Registrar.find_by(reference_no: transaction.parsed_ref_number) return unless registrar_user @@ -128,6 +145,16 @@ class Invoice < ApplicationRecord private + def receipt_date_status + if paid? + receipt_date + elsif cancelled? + I18n.t(:cancelled) + else + I18n.t(:unpaid) + end + end + def apply_default_buyer_vat_no self.buyer_vat_no = buyer.vat_no end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb index 122a04ff5..a2c1305a3 100644 --- a/app/services/csv_generator.rb +++ b/app/services/csv_generator.rb @@ -12,6 +12,6 @@ class CsvGenerator private def self.custom_csv(class_name) - [Version::DomainVersion, Version::ContactVersion, Domain, Contact, Invoice].include?(class_name) + [Version::DomainVersion, Version::ContactVersion, Domain, Contact, Invoice, Account].include?(class_name) end end diff --git a/test/fixtures/files/invoices.csv b/test/fixtures/files/invoices.csv new file mode 100644 index 000000000..641cfe036 --- /dev/null +++ b/test/fixtures/files/invoices.csv @@ -0,0 +1,3 @@ +Number,Buyer,Due Date,Receipt Date,Issue Date,Total,Currency,Seller Name +2,Best Names,2010-07-06,Unpaid,2010-07-05,16.5,EUR,Seller Ltd +1,Best Names,2010-07-06,2010-07-05,2010-07-05,16.5,EUR,Seller Ltd diff --git a/test/system/admin_area/invoices_test.rb b/test/system/admin_area/invoices_test.rb index 40a50e1c7..a8d0a8a75 100644 --- a/test/system/admin_area/invoices_test.rb +++ b/test/system/admin_area/invoices_test.rb @@ -40,4 +40,14 @@ class AdminAreaInvoicesTest < ApplicationSystemTestCase assert_current_path admin_invoice_path(@invoice) assert_text 'Invoice has been sent' end + + def test_download_invoices_list_as_csv + travel_to Time.zone.parse('2010-07-05 10:30') + + visit admin_invoices_url + click_link('CSV') + + assert_equal "attachment; filename=\"invoices_#{Time.zone.now.to_formatted_s(:number)}.csv\"; filename*=UTF-8''invoices_#{Time.zone.now.to_formatted_s(:number)}.csv", response_headers['Content-Disposition'] + assert_equal file_fixture('invoices.csv').read, page.body + end end From 1fac9d9618e3a250c544d2b2171d17ba6db33e9a Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Mon, 14 Mar 2022 12:12:22 +0200 Subject: [PATCH 12/19] Fix admin accounts CSV output --- app/models/account.rb | 8 ++++++++ test/fixtures/files/accounts.csv | 4 ++++ test/system/admin_area/accounts_test.rb | 12 ++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 test/fixtures/files/accounts.csv diff --git a/app/models/account.rb b/app/models/account.rb index fe0820888..73911817c 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -12,4 +12,12 @@ class Account < ApplicationRecord def activities account_activities end + + def as_csv_row + [id, balance, currency, registrar] + end + + def self.csv_header + ['Id', 'Balance', 'Currency', 'Registrar'].freeze + end end diff --git a/test/fixtures/files/accounts.csv b/test/fixtures/files/accounts.csv new file mode 100644 index 000000000..5bc44fc48 --- /dev/null +++ b/test/fixtures/files/accounts.csv @@ -0,0 +1,4 @@ +Id,Balance,Currency,Registrar +112846265,100.0,EUR,Best Names +298486374,100.0,EUR,Good Names +597560588,0.0,EUR,Not in use diff --git a/test/system/admin_area/accounts_test.rb b/test/system/admin_area/accounts_test.rb index f07ced9c3..393c3445a 100644 --- a/test/system/admin_area/accounts_test.rb +++ b/test/system/admin_area/accounts_test.rb @@ -29,4 +29,16 @@ class AdminAccountsSystemTest < ApplicationSystemTestCase assert_text 'Account has been successfully updated' assert_text '234' end + + def test_download_accounts_list_as_csv + travel_to Time.zone.parse('2010-07-05 10:30') + + get admin_accounts_path(format: :csv) + + assert_response :ok + assert_equal 'text/csv; charset=utf-8', response.headers['Content-Type'] + assert_equal %(attachment; filename="accounts_#{Time.zone.now.to_formatted_s(:number)}.csv"; filename*=UTF-8''accounts_#{Time.zone.now.to_formatted_s(:number)}.csv), + response.headers['Content-Disposition'] + assert_equal file_fixture('accounts.csv').read, response.body + end end From dd513b63138f24cad6e353ae8252ba1b2e644d70 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Mon, 14 Mar 2022 12:43:53 +0200 Subject: [PATCH 13/19] Remove `freeze` method call at `csv_header` --- app/models/account.rb | 2 +- app/models/contact.rb | 2 +- app/models/domain.rb | 2 +- app/models/invoice.rb | 2 +- app/models/version/contact_version.rb | 2 +- app/models/version/domain_version.rb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index 73911817c..334d292f2 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -18,6 +18,6 @@ class Account < ApplicationRecord end def self.csv_header - ['Id', 'Balance', 'Currency', 'Registrar'].freeze + ['Id', 'Balance', 'Currency', 'Registrar'] end end diff --git a/app/models/contact.rb b/app/models/contact.rb index 367777efb..f44b28f35 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -590,6 +590,6 @@ class Contact < ApplicationRecord end def self.csv_header - ['Name', 'ID', 'Ident', 'E-mail', 'Created at', 'Registrar', 'Phone'].freeze + ['Name', 'ID', 'Ident', 'E-mail', 'Created at', 'Registrar', 'Phone'] end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 2f084ed4d..3728b0de1 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -779,7 +779,7 @@ class Domain < ApplicationRecord end def self.csv_header - ['Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data'].freeze + ['Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data'] end def self.pdf(html) diff --git a/app/models/invoice.rb b/app/models/invoice.rb index d0a1950a5..80dbc6417 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -131,7 +131,7 @@ class Invoice < ApplicationRecord end def self.csv_header - ['Number', 'Buyer', 'Due Date', 'Receipt Date', 'Issue Date', 'Total', 'Currency', 'Seller Name'].freeze + ['Number', 'Buyer', 'Due Date', 'Receipt Date', 'Issue Date', 'Total', 'Currency', 'Seller Name'] end def self.create_from_transaction!(transaction) diff --git a/app/models/version/contact_version.rb b/app/models/version/contact_version.rb index 498e6d468..669c422fe 100644 --- a/app/models/version/contact_version.rb +++ b/app/models/version/contact_version.rb @@ -19,6 +19,6 @@ class Version::ContactVersion < PaperTrail::Version end def self.csv_header - ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'].freeze + ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'] end end diff --git a/app/models/version/domain_version.rb b/app/models/version/domain_version.rb index 52b10fc53..bef5208f3 100644 --- a/app/models/version/domain_version.rb +++ b/app/models/version/domain_version.rb @@ -57,6 +57,6 @@ class Version::DomainVersion < PaperTrail::Version end def self.csv_header - ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze + ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'] end end From fd41d773904afb346708f30dbbfac6a4de4d6a30 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Mon, 14 Mar 2022 14:46:31 +0200 Subject: [PATCH 14/19] Move contact ident description to helper method --- app/helpers/application_helper.rb | 8 ++++++++ app/views/admin/contact_versions/index.haml | 2 +- app/views/admin/contact_versions/show.haml | 2 +- app/views/admin/contacts/index.haml | 2 +- app/views/admin/contacts/partials/_general.haml | 2 +- app/views/registrar/contacts/index.html.erb | 2 +- app/views/registrar/contacts/list_pdf.html.erb | 2 +- app/views/registrar/contacts/partials/_general.haml | 2 +- 8 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6829040c2..122fc40d4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -9,6 +9,14 @@ module ApplicationHelper "background-image: url(#{image_path("#{unstable_env}.png")});" end + def ident_for(contact) + ident = contact.ident + description = "[#{contact.ident_country_code} #{contact.ident_type}]" + description.prepend("#{ident} ") if ident.present? + + description + end + def current_commit_link hash = `git rev-parse --short HEAD` current_repo = `git remote get-url origin`.gsub('com:', 'com/') diff --git a/app/views/admin/contact_versions/index.haml b/app/views/admin/contact_versions/index.haml index 97c267d30..8f973ee40 100644 --- a/app/views/admin/contact_versions/index.haml +++ b/app/views/admin/contact_versions/index.haml @@ -69,7 +69,7 @@ %tr %td= link_to(contact.name, admin_contact_version_path(version.id)) %td= contact.code - %td= contact.ident_human_description + %td= ident_for(contact) %td - if contact.registrar = link_to(contact.registrar, admin_registrar_path(contact.registrar)) diff --git a/app/views/admin/contact_versions/show.haml b/app/views/admin/contact_versions/show.haml index 57c8c3ccc..546ff4287 100644 --- a/app/views/admin/contact_versions/show.haml +++ b/app/views/admin/contact_versions/show.haml @@ -22,7 +22,7 @@ %dt= t(:ident) %dd{class: changing_css_class(@version,"ident_country_code", "ident_type", "ident")} - = contact.ident_human_description + = ident_for(contact) - if contact.email.present? %dt= t(:email) diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml index b4198b8cc..0812913a1 100644 --- a/app/views/admin/contacts/index.haml +++ b/app/views/admin/contacts/index.haml @@ -100,7 +100,7 @@ %tr %td= link_to(contact, admin_contact_path(contact)) %td= contact.code - %td= contact.ident_human_description + %td= ident_for(contact) %td= contact.email %td= l(contact.created_at, format: :short) %td diff --git a/app/views/admin/contacts/partials/_general.haml b/app/views/admin/contacts/partials/_general.haml index 4b8d4ec32..2396861fb 100644 --- a/app/views/admin/contacts/partials/_general.haml +++ b/app/views/admin/contacts/partials/_general.haml @@ -14,7 +14,7 @@ %br %dt.left_25= t(:ident) - %dd.left_25= @contact.ident_human_description + %dd.left_25= ident_for(@contact) %dt.left_25= t(:email) %dd.left_25= @contact.email diff --git a/app/views/registrar/contacts/index.html.erb b/app/views/registrar/contacts/index.html.erb index 35683360e..4a7e8759a 100644 --- a/app/views/registrar/contacts/index.html.erb +++ b/app/views/registrar/contacts/index.html.erb @@ -44,7 +44,7 @@ <%= contact.code %> - <%= contact.ident_human_description %> + <%= ident_for(contact) %> <%= l(contact.created_at, format: :short) %> diff --git a/app/views/registrar/contacts/list_pdf.html.erb b/app/views/registrar/contacts/list_pdf.html.erb index 52e5956dd..b9bbb1c0e 100644 --- a/app/views/registrar/contacts/list_pdf.html.erb +++ b/app/views/registrar/contacts/list_pdf.html.erb @@ -20,7 +20,7 @@ <%= contact %> <%= contact.code %> - <%= contact.ident_human_description %> + <%= ident_for(contact) %> <%= l(contact.created_at, format: :short) %> <%= contact.registrar %> diff --git a/app/views/registrar/contacts/partials/_general.haml b/app/views/registrar/contacts/partials/_general.haml index 4e2a92621..5fc8ec027 100644 --- a/app/views/registrar/contacts/partials/_general.haml +++ b/app/views/registrar/contacts/partials/_general.haml @@ -14,7 +14,7 @@ %br %dt= t(:ident) - %dd= @contact.ident_human_description + %dd= ident_for(@contact) %dt= t(:email) %dd= @contact.email From daafa756aa292dbdcf979f613ae3c0bd101dbc0d Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Thu, 31 Mar 2022 16:33:47 +0300 Subject: [PATCH 15/19] Refactor account activity csv generation --- app/models/account_activity.rb | 19 +++++++------------ app/services/csv_generator.rb | 8 +++----- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/app/models/account_activity.rb b/app/models/account_activity.rb index 05873a2a6..38fa70358 100644 --- a/app/models/account_activity.rb +++ b/app/models/account_activity.rb @@ -11,6 +11,7 @@ class AccountActivity < ApplicationRecord UPDATE_CREDIT = 'update_credit'.freeze after_create :update_balance + def update_balance account.balance += sum account.save @@ -19,23 +20,17 @@ class AccountActivity < ApplicationRecord save end + def as_csv_row + [account.registrar.try(:code), description, I18n.t(activity_type), I18n.l(created_at), sum] + end + class << self def types_for_select [CREATE, RENEW, ADD_CREDIT, UPDATE_CREDIT].map { |x| [I18n.t(x), x] } end - def to_csv - attributes = %w(description activity_type created_at sum) - - CSV.generate(headers: true) do |csv| - csv << %w(registrar description activity_type receipt_date sum) - - all.each do |x| - attrs = [x.account.registrar.try(:code)] - attrs += attributes.map { |attr| x.send(attr) } - csv << attrs - end - end + def csv_header + ['Registrar', 'Description', 'Activity Type', 'Receipt Date', 'Sum'] end end end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb index a2c1305a3..fd47fac45 100644 --- a/app/services/csv_generator.rb +++ b/app/services/csv_generator.rb @@ -1,7 +1,7 @@ class CsvGenerator def self.generate_csv(objects) class_name = objects.first.class - return objects.to_csv unless custom_csv(class_name) + return objects.to_csv unless custom_csv?(class_name) CSV.generate do |csv| csv << class_name.csv_header @@ -9,9 +9,7 @@ class CsvGenerator end end - private - - def self.custom_csv(class_name) - [Version::DomainVersion, Version::ContactVersion, Domain, Contact, Invoice, Account].include?(class_name) + def self.custom_csv?(class_name) + [Version::DomainVersion, Version::ContactVersion, Domain, Contact, Invoice, Account, AccountActivity].include?(class_name) end end From e50501f13f0779253ea383d3d6702fd551a5a110 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Fri, 1 Apr 2022 10:59:04 +0300 Subject: [PATCH 16/19] Migrate `ToCsv` module to `CsvGenerator` service --- .../admin/account_activities_controller.rb | 2 +- .../account_activities_controller.rb | 2 +- .../registrar/contacts_controller.rb | 2 +- app/lib/to_csv.rb | 10 ----- app/models/account.rb | 1 - app/models/api_log/epp_log.rb | 4 +- app/models/api_log/repp_log.rb | 4 +- app/models/blocked_domain.rb | 1 - app/models/contact.rb | 9 ----- app/models/dispute.rb | 1 - app/models/domain.rb | 15 ------- app/models/invoice.rb | 1 - app/models/reserved_domain.rb | 1 - app/models/version/contact_version.rb | 1 - app/models/version/domain_version.rb | 1 - app/services/csv_generator.rb | 39 ++++++++++++++----- 16 files changed, 34 insertions(+), 60 deletions(-) delete mode 100644 app/lib/to_csv.rb diff --git a/app/controllers/admin/account_activities_controller.rb b/app/controllers/admin/account_activities_controller.rb index ebd44e28e..0d22a4298 100644 --- a/app/controllers/admin/account_activities_controller.rb +++ b/app/controllers/admin/account_activities_controller.rb @@ -35,7 +35,7 @@ module Admin respond_to do |format| format.html format.csv do - send_data @q.result.to_csv, filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" + send_data CsvGenerator.generate_csv(@q.result), filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" end end diff --git a/app/controllers/registrar/account_activities_controller.rb b/app/controllers/registrar/account_activities_controller.rb index 55e53f8fc..7b5281275 100644 --- a/app/controllers/registrar/account_activities_controller.rb +++ b/app/controllers/registrar/account_activities_controller.rb @@ -20,7 +20,7 @@ class Registrar respond_to do |format| format.html { @account_activities = @q.result.page(params[:page]) } format.csv do - send_data @q.result.to_csv, filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" + send_data CsvGenerator.generate_csv(@q.result), filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" end end diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb index ec4ce5129..812e278e5 100644 --- a/app/controllers/registrar/contacts_controller.rb +++ b/app/controllers/registrar/contacts_controller.rb @@ -40,7 +40,7 @@ class Registrar @contacts = @contacts.per(contacts_per_page) if contacts_per_page.positive? end format.csv do - raw_csv = contacts.to_csv + raw_csv = CsvGenerator.generate_csv(contacts) send_data raw_csv, filename: 'contacts.csv', type: "#{Mime[:csv]}; charset=utf-8" end format.pdf do diff --git a/app/lib/to_csv.rb b/app/lib/to_csv.rb deleted file mode 100644 index 32c288978..000000000 --- a/app/lib/to_csv.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ToCsv - def to_csv - CSV.generate do |csv| - csv << column_names - all.find_each do |item| - csv << item.attributes.values_at(*column_names) - end - end - end -end diff --git a/app/models/account.rb b/app/models/account.rb index 334d292f2..7639c61dd 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -1,5 +1,4 @@ class Account < ApplicationRecord - extend ToCsv include Versions belongs_to :registrar, required: true diff --git a/app/models/api_log/epp_log.rb b/app/models/api_log/epp_log.rb index feed1ecad..c89569be5 100644 --- a/app/models/api_log/epp_log.rb +++ b/app/models/api_log/epp_log.rb @@ -1,5 +1,3 @@ module ApiLog - class EppLog < Db - extend ToCsv - end + class EppLog < Db; end end diff --git a/app/models/api_log/repp_log.rb b/app/models/api_log/repp_log.rb index 62dcee238..540a9043a 100644 --- a/app/models/api_log/repp_log.rb +++ b/app/models/api_log/repp_log.rb @@ -1,5 +1,3 @@ module ApiLog - class ReppLog < Db - extend ToCsv - end + class ReppLog < Db; end end diff --git a/app/models/blocked_domain.rb b/app/models/blocked_domain.rb index fb50a8b52..f82faa771 100644 --- a/app/models/blocked_domain.rb +++ b/app/models/blocked_domain.rb @@ -1,6 +1,5 @@ class BlockedDomain < ApplicationRecord include Versions - extend ToCsv before_save :generate_data after_destroy :remove_data diff --git a/app/models/contact.rb b/app/models/contact.rb index f44b28f35..dab2dd6d9 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -188,15 +188,6 @@ class Contact < ApplicationRecord ] end - def to_csv - CSV.generate do |csv| - csv << column_names - all.each do |contact| - csv << contact.attributes.values_at(*column_names) - end - end - end - def pdf(html) kit = PDFKit.new(html) kit.to_pdf diff --git a/app/models/dispute.rb b/app/models/dispute.rb index cbf93566a..f5a948355 100644 --- a/app/models/dispute.rb +++ b/app/models/dispute.rb @@ -1,5 +1,4 @@ class Dispute < ApplicationRecord - extend ToCsv include WhoisStatusPopulate validates :domain_name, :password, :starts_at, :expires_at, presence: true before_validation :fill_empty_passwords, :set_expiry_date diff --git a/app/models/domain.rb b/app/models/domain.rb index 3728b0de1..53e2ddf9b 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -289,21 +289,6 @@ class Domain < ApplicationRecord ) end - def to_csv - CSV.generate do |csv| - headers = column_names.dup - swap_elements(headers, [[0, 1], [1, 5]]) - headers[0] = 'Domain' - headers[1] = headers[1].humanize - csv << headers - all.find_each do |item| - row = item.attributes.values_at(*column_names) - swap_elements(row, [[0, 1], [1, 5]]) - csv << row - end - end - end - private def registrant_user_domains_by_registrant(registrant_user) diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 80dbc6417..c31ae15c4 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -3,7 +3,6 @@ class Invoice < ApplicationRecord include Invoice::Cancellable include Invoice::Payable include Invoice::BookKeeping - extend ToCsv belongs_to :buyer, class_name: 'Registrar' has_one :account_activity diff --git a/app/models/reserved_domain.rb b/app/models/reserved_domain.rb index 5d585e5d9..10d5edd11 100644 --- a/app/models/reserved_domain.rb +++ b/app/models/reserved_domain.rb @@ -1,5 +1,4 @@ class ReservedDomain < ApplicationRecord - extend ToCsv include Versions # version/reserved_domain_version.rb include WhoisStatusPopulate before_save :fill_empty_passwords diff --git a/app/models/version/contact_version.rb b/app/models/version/contact_version.rb index 669c422fe..d3ff1130c 100644 --- a/app/models/version/contact_version.rb +++ b/app/models/version/contact_version.rb @@ -1,5 +1,4 @@ class Version::ContactVersion < PaperTrail::Version - extend ToCsv include VersionSession self.table_name = :log_contacts diff --git a/app/models/version/domain_version.rb b/app/models/version/domain_version.rb index bef5208f3..e84fc9da2 100644 --- a/app/models/version/domain_version.rb +++ b/app/models/version/domain_version.rb @@ -1,5 +1,4 @@ class Version::DomainVersion < PaperTrail::Version - extend ToCsv include VersionSession self.table_name = :log_domains diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb index fd47fac45..16901dcff 100644 --- a/app/services/csv_generator.rb +++ b/app/services/csv_generator.rb @@ -1,15 +1,34 @@ class CsvGenerator - def self.generate_csv(objects) - class_name = objects.first.class - return objects.to_csv unless custom_csv?(class_name) + class << self + def generate_csv(objects) + @class_name = objects.first.class + return default_generation(objects) unless custom_csv? - CSV.generate do |csv| - csv << class_name.csv_header - objects.each { |object| csv << object.as_csv_row } + CSV.generate do |csv| + csv << @class_name.csv_header + objects.each { |object| csv << object.as_csv_row } + end + end + + private + + def default_generation(objects) + CSV.generate do |csv| + csv << @class_name.column_names + objects.each { |object| csv << object.attributes.values_at(*@class_name.column_names) } + end + end + + def custom_csv? + [ + Version::DomainVersion, + Version::ContactVersion, + Domain, + Contact, + Invoice, + Account, + AccountActivity + ].include?(@class_name) end end - - def self.custom_csv?(class_name) - [Version::DomainVersion, Version::ContactVersion, Domain, Contact, Invoice, Account, AccountActivity].include?(class_name) - end end From aef30eeb4d76612c41be627c2fc0a6da8e65f40e Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Fri, 1 Apr 2022 11:50:35 +0300 Subject: [PATCH 17/19] Improve default csv generation --- .../admin/account_activities_controller.rb | 3 ++- .../account_activities_controller.rb | 3 ++- app/models/domain.rb | 7 ++++-- app/models/invoice.rb | 2 +- app/services/csv_generator.rb | 23 ++++++++----------- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/controllers/admin/account_activities_controller.rb b/app/controllers/admin/account_activities_controller.rb index 0d22a4298..452acaee1 100644 --- a/app/controllers/admin/account_activities_controller.rb +++ b/app/controllers/admin/account_activities_controller.rb @@ -35,7 +35,8 @@ module Admin respond_to do |format| format.html format.csv do - send_data CsvGenerator.generate_csv(@q.result), filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" + raw_csv = CsvGenerator.generate_csv(@q.result) + send_data raw_csv, filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" end end diff --git a/app/controllers/registrar/account_activities_controller.rb b/app/controllers/registrar/account_activities_controller.rb index 7b5281275..0ad8c3d5a 100644 --- a/app/controllers/registrar/account_activities_controller.rb +++ b/app/controllers/registrar/account_activities_controller.rb @@ -20,7 +20,8 @@ class Registrar respond_to do |format| format.html { @account_activities = @q.result.page(params[:page]) } format.csv do - send_data CsvGenerator.generate_csv(@q.result), filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" + raw_csv = CsvGenerator.generate_csv(@q.result) + send_data raw_csv, filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv" end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 53e2ddf9b..2c6069cd1 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -748,7 +748,7 @@ class Domain < ApplicationRecord statuses, contacts.pluck(:code), force_delete_date, - force_delete_data + force_delete_data, ] end @@ -764,7 +764,10 @@ class Domain < ApplicationRecord end def self.csv_header - ['Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data'] + [ + 'Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', + 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data', + ] end def self.pdf(html) diff --git a/app/models/invoice.rb b/app/models/invoice.rb index c31ae15c4..6ba3a158d 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -125,7 +125,7 @@ class Invoice < ApplicationRecord issue_date, total, currency, - seller_name + seller_name, ] end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb index 16901dcff..d92beeddc 100644 --- a/app/services/csv_generator.rb +++ b/app/services/csv_generator.rb @@ -1,11 +1,11 @@ class CsvGenerator class << self def generate_csv(objects) - @class_name = objects.first.class - return default_generation(objects) unless custom_csv? + class_name = objects.first.class + return default_generation(objects) unless custom_csv?(class_name) CSV.generate do |csv| - csv << @class_name.csv_header + csv << class_name.csv_header objects.each { |object| csv << object.as_csv_row } end end @@ -14,21 +14,16 @@ class CsvGenerator def default_generation(objects) CSV.generate do |csv| - csv << @class_name.column_names - objects.each { |object| csv << object.attributes.values_at(*@class_name.column_names) } + csv << objects.column_names + objects.all.find_each { |object| csv << object.attributes.values_at(*objects.column_names) } end end - def custom_csv? + def custom_csv?(class_name) [ - Version::DomainVersion, - Version::ContactVersion, - Domain, - Contact, - Invoice, - Account, - AccountActivity - ].include?(@class_name) + Version::DomainVersion, Version::ContactVersion, Domain, + Contact, Invoice, Account, AccountActivity + ].include?(class_name) end end end From b6a5bc73cad4ea291c2d64a1ad27fa2d9f8052fc Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Fri, 1 Apr 2022 13:20:13 +0300 Subject: [PATCH 18/19] Code climate refactor --- app/models/domain.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index 2c6069cd1..7afd8046e 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -766,7 +766,7 @@ class Domain < ApplicationRecord def self.csv_header [ 'Domain', 'Registrant', 'Valid to', 'Registrar', 'Created at', - 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data', + 'Statuses', 'Contacts code', 'Force delete date', 'Force delete data' ] end From c240aef717b1c406f3678b6a1e1a84ba573432a8 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Tue, 5 Apr 2022 12:06:53 +0300 Subject: [PATCH 19/19] Improve csv tests --- test/fixtures/files/contacts.csv | 8 -------- test/fixtures/files/domains.csv | 5 ----- test/system/admin_area/contacts/csv_test.rb | 13 ++++++++----- test/system/admin_area/domains/csv_test.rb | 12 +++++++----- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/test/fixtures/files/contacts.csv b/test/fixtures/files/contacts.csv index 73d9104af..9d8ca5357 100644 --- a/test/fixtures/files/contacts.csv +++ b/test/fixtures/files/contacts.csv @@ -1,10 +1,2 @@ Name,ID,Ident,E-mail,Created at,Registrar,Phone -John,john-001,1234 [US priv],john@inbox.test,2010-07-05 07:30:00,Best Names,+555.555 -William,william-001,12345 [US priv],william@inbox.test,2010-07-05 07:30:00,Best Names,+555.555 -Jane,jane-001,123456 [US priv],jane@mail.test,2010-07-05 07:30:00,Best Names,+555.555 Acme Ltd,acme-ltd-001,1234567 [US org],acme@outlook.test,2010-07-05 07:30:00,Best Names,+555.555 -Jack,jack-001,12345678 [US org],jack@inbox.test,2010-07-05 07:30:00,Good Names,+555.555 -William,william-002,12345 [US priv],william@inbox.test,2010-07-05 07:30:00,Good Names,+555.555 -Registrar Ltd,registrarltd-001,1234567890 [US org],registrar@inbox.test,2010-07-05 07:30:00,Good Names,+555.555 -any,invalid,[ ],invalid@invalid.test,2010-07-05 07:30:00,Best Names, -any,invalid_email,[ ],invalid@invalid.,2010-07-05 07:30:00,Best Names, diff --git a/test/fixtures/files/domains.csv b/test/fixtures/files/domains.csv index 69e9df8a8..b8261ebc2 100644 --- a/test/fixtures/files/domains.csv +++ b/test/fixtures/files/domains.csv @@ -1,7 +1,2 @@ Domain,Registrant,Valid to,Registrar,Created at,Statuses,Contacts code,Force delete date,Force delete data -shop.test,John,2010-07-04 21:00:00,Best Names,2010-07-05 07:30:00,"[""ok""]","[""william-001"", ""jane-001"", ""acme-ltd-001""]",2010-07-08, -airport.test,John,2010-07-05 00:00:00,Best Names,2010-07-05 07:30:00,"[""ok""]","[""john-001"", ""william-001"", ""william-001""]",, -library.test,Acme Ltd,2010-07-05 00:00:00,Best Names,2010-07-05 07:30:00,"[""inactive""]","[""john-001"", ""acme-ltd-001""]",, metro.test,Jack,2010-07-05 00:00:00,Good Names,2010-07-05 07:30:00,[],"[""jack-001"", ""jack-001""]",, -hospital.test,John,2010-07-05 00:00:00,Good Names,2010-07-05 07:30:00,"[""inactive""]","[""john-001"", ""john-001""]",, -invalid.test,any,2010-07-04 21:00:00,Best Names,2010-07-05 07:30:00,"[""inactive""]","[""invalid"", ""invalid""]",, diff --git a/test/system/admin_area/contacts/csv_test.rb b/test/system/admin_area/contacts/csv_test.rb index 552bcf437..de5bd440e 100644 --- a/test/system/admin_area/contacts/csv_test.rb +++ b/test/system/admin_area/contacts/csv_test.rb @@ -1,14 +1,17 @@ require 'application_system_test_case' class ContactsCsvTest < ApplicationSystemTestCase - setup { sign_in users(:admin) } + setup do + sign_in users(:admin) + Domain.destroy_all + Contact.all.each { |contact| contact.destroy unless contact.name == 'Acme Ltd' } + end def test_download_contacts_list_as_csv travel_to Time.zone.parse('2010-07-05 10:30') - Contact.all.each do |contact| - contact.created_at = Time.zone.now - contact.save(:validate => false) - end + contact = Contact.first + contact.created_at = Time.zone.now + contact.save(validate: false) visit admin_contacts_url click_link('CSV') diff --git a/test/system/admin_area/domains/csv_test.rb b/test/system/admin_area/domains/csv_test.rb index 568815dd7..691a8dc50 100644 --- a/test/system/admin_area/domains/csv_test.rb +++ b/test/system/admin_area/domains/csv_test.rb @@ -1,14 +1,16 @@ require 'application_system_test_case' class DomainsCsvTest < ApplicationSystemTestCase - setup { sign_in users(:admin) } + setup do + sign_in users(:admin) + Domain.all.each { |domain| domain.destroy unless domain.name == 'metro.test' } + end def test_download_domains_list_as_csv travel_to Time.zone.parse('2010-07-05 10:30') - Domain.all.each do |domain| - domain.created_at = Time.zone.now - domain.save(:validate => false) - end + domain = Domain.first + domain.created_at = Time.zone.now + domain.save(validate: false) visit admin_domains_url click_link('CSV')