From e6301fc5c0f4c5fc2ad78848e5bec1f5edea1b65 Mon Sep 17 00:00:00 2001 From: Thomas Scherz Date: Tue, 7 May 2024 12:02:48 -0400 Subject: [PATCH] Fixes null values in export function. --- exports/software_records.rb | 168 ++++++++------------------ spec/exports/software_records_spec.rb | 42 ++++++- spec/factories/software_records.rb | 27 +++++ 3 files changed, 117 insertions(+), 120 deletions(-) diff --git a/exports/software_records.rb b/exports/software_records.rb index 457911bd..f3673924 100644 --- a/exports/software_records.rb +++ b/exports/software_records.rb @@ -9,132 +9,62 @@ class SoftwareRecords < ApplicationRecord def software_records file = "#{Dir.pwd}/public/software_records.csv" software_records = SoftwareRecords.all - # general metadata - headers = ['Software Record', 'Description', 'Status', 'Created on', 'Software Type', 'Authentication Type', 'Vendor Record', 'Departments', 'Date Implemented', 'Date of upgrade', 'Developers', 'Tech Leads', 'Product Owners', 'Admin Users', 'Languages Used', 'Production URL', 'Source Code URL', 'User Seats', 'Annual Fees', 'Support Contract', 'Hosting Environment', - 'Current Version', 'Notes', 'Business Value', 'IT Quality', 'Created By'] - # change management metadata - headers += ['Requires Chanage Management review?', 'Last Security Scan', 'Last Accessibility Scan', 'Last OGC Review', 'Last Infosec Review', 'CM Stakeholders', 'CM Other Notes'] - # server env metadtata - headers += ['QA URL', 'Dev_URL', 'Prod_URL', 'Production Support Servers', 'Last Record Change', 'Track Uptime', 'Monitor Health', 'Monitor Errors'] + headers = [ + 'Software Record', 'Description', 'Status', 'Created on', 'Software Type', + 'Authentication Type', 'Vendor Record', 'Departments', 'Date Implemented', + 'Date of upgrade', 'Developers', 'Tech Leads', 'Product Owners', + 'Admin Users', 'Languages Used', 'Production URL', 'Source Code URL', + 'User Seats', 'Annual Fees', 'Support Contract', 'Hosting Environment', + 'Current Version', 'Notes', 'Business Value', 'IT Quality', 'Created By', + 'Requires Change Management review?', 'Last Security Scan', + 'Last Accessibility Scan', 'Last OGC Review', 'Last Infosec Review', + 'CM Stakeholders', 'CM Other Notes', 'QA URL', 'Dev_URL', 'Prod_URL', + 'Production Support Servers', 'Last Record Change', 'Track Uptime', + 'Monitor Health', 'Monitor Errors' + ] CSV.open(file, 'w', write_headers: true, headers:) do |writer| software_records.each do |software_record| - tech_leads = software_record.tech_leads.to_s.gsub!('---', '').to_s - tech_leads = tech_leads.gsub!(/\n/, '-').to_s - all_tech_leads = tech_leads.split('- ') - the_techleads = '' - all_tech_lead_count = 0 - all_tech_leads.each do |each_tech_lead| - if each_tech_lead.to_s == '-' - all_tech_lead_count += 1 - else - each_tech_lead = if each_tech_lead.include?('-') - each_tech_lead.gsub('-', '').to_s - else - each_tech_lead - end - all_tech_lead_count += 1 - the_techleads += each_tech_lead - the_techleads += ',' if all_tech_lead_count != all_tech_leads.size - end - end - - the_techleads = '' if the_techleads.to_s == "''" - - departments = software_record.departments.to_s.gsub!('---', '').to_s - departments = departments.gsub!(/\n/, '-').to_s - all_departments = departments.split('- ') - the_departments = '' - all_departments_count = 0 - all_departments.each do |each_department| - if each_department.to_s == '-' - all_departments_count += 1 - else - each_department = if each_department.include?('-') - each_department.gsub('-', '').to_s - else - each_department - end - all_departments_count += 1 - the_departments += each_department - the_departments += ',' if all_departments_count != all_tech_leads.size - end - end - - the_departments = '' if the_departments.to_s == "''" - - developers = software_record.developers.to_s.gsub!('---', '').to_s - developers = developers.gsub!(/\n/, '-').to_s - all_developers = developers.split('- ') - the_developers = '' - all_developers_count = 0 - all_developers.each do |each_developer| - if each_developer.to_s == '-' - all_developers_count += 1 - else - each_developer = if each_developer.include?('-') - each_developer.gsub('-', '').to_s - else - each_developer - end - all_developers_count += 1 - the_developers += each_developer - the_developers += ',' if all_developers_count != all_developers.size - end - end - - the_developers = '' if the_developers.to_s == "''" - - product_owners = software_record.product_owners.to_s.gsub!('---', '').to_s - product_owners = product_owners.gsub!(/\n/, '-').to_s - all_product_owners = product_owners.split('- ') - the_product_owners = '' - all_product_owners_count = 0 - all_product_owners.each do |each_product_owner| - if each_product_owner.to_s == '-' - all_product_owners_count += 1 - else - each_product_owner = if each_product_owner.include?('-') - each_product_owner.gsub('-', '').to_s - else - each_product_owner - end - all_product_owners_count += 1 - the_product_owners += each_product_owner - the_product_owners += ',' if all_product_owners_count != all_product_owners.size - end - end - - the_product_owners = '' if the_product_owners.to_s == "''" - - admin_users = software_record.admin_users.to_s.gsub!('---', '').to_s - admin_users = admin_users.gsub!(/\n/, '-').to_s - all_admin_users = admin_users.split('- ') - the_admin_users = '' - all_admin_users_count = 0 - all_admin_users.each do |each_admin_user| - if each_admin_user.to_s == '-' - all_admin_users_count += 1 - else - each_admin_user = if each_admin_user.include?('-') - each_admin_user.gsub('-', '').to_s - else - each_admin_user - end - all_admin_users_count += 1 - the_admin_users += each_admin_user - the_admin_users += ',' if all_admin_users_count != all_admin_users.size - end - end - - the_admin_users = '' if the_admin_users.to_s == "''" - - writer << [software_record.title, software_record.description, Status.find_by(id: software_record.status_id).title, software_record.created_at, SoftwareType.find_by(id: software_record.software_type_id).title, software_record.authentication_type, VendorRecord.find_by(id: software_record.vendor_record_id).title, the_departments, software_record.date_implemented, - software_record.date_of_upgrade, the_developers, the_techleads, the_product_owners, the_admin_users, software_record.languages_used, software_record.production_url, software_record.source_code_url, software_record.user_seats, software_record.annual_fees, software_record.support_contract, HostingEnvironment.find_by(id: software_record.hosting_environment_id).title, software_record.current_version, software_record.notes, software_record.business_value, software_record.it_quality, software_record.created_by, software_record.requires_cm, software_record.last_security_scan, software_record.last_accessibility_scan, software_record.last_ogc_review, last_info_sec_review, software_record.cm_stakeholders, software_record.cm_other_notes, software_record.qa_url, software_record.dev_url, software_record.prod_url, software_record.production_support_servers, software_record.last_record_change, software_record.track_uptime, software_record.monitor_health, software_record.monitor_errors] + writer << [ + software_record.title, software_record.description, + Status.find_by(id: software_record.status_id)&.title, + software_record.created_at, + SoftwareType.find_by(id: software_record.software_type_id)&.title, + software_record.authentication_type, + VendorRecord.find_by(id: software_record.vendor_record_id)&.title, + clean_and_format(software_record.departments), + software_record.date_implemented, software_record.date_of_upgrade, + clean_and_format(software_record.developers), + clean_and_format(software_record.tech_leads), + clean_and_format(software_record.product_owners), + clean_and_format(software_record.admin_users), + software_record.languages_used, software_record.production_url, + software_record.source_code_url, software_record.user_seats, + software_record.annual_fees, software_record.support_contract, + HostingEnvironment.find_by(id: software_record.hosting_environment_id)&.title, + software_record.current_version, software_record.notes, + software_record.business_value, software_record.it_quality, + software_record.created_by, software_record.requires_cm, + software_record.last_security_scan, software_record.last_accessibility_scan, + software_record.last_ogc_review, software_record.last_info_sec_review, + software_record.cm_stakeholders, software_record.cm_other_notes, + software_record.qa_url, software_record.dev_url, software_record.prod_url, + software_record.production_support_servers, software_record.last_record_change, + software_record.track_uptime, software_record.monitor_health, + software_record.monitor_errors + ] end end end + + private + + def clean_and_format(attribute) + formatted_attribute = attribute.to_s.gsub('---', '').gsub("\n", '-') + parts = formatted_attribute.split('- ').reject { |part| part == '-' } + parts.map { |part| part.gsub('-', '').strip }.join(',') + end end records = SoftwareRecords.new diff --git a/spec/exports/software_records_spec.rb b/spec/exports/software_records_spec.rb index e600dd14..eb14ad5a 100644 --- a/spec/exports/software_records_spec.rb +++ b/spec/exports/software_records_spec.rb @@ -1,8 +1,48 @@ # frozen_string_literal: true require "#{Dir.pwd}/exports/software_records.rb" +require 'rails_helper' +require 'csv' RSpec.describe SoftwareRecords do - describe 'software_records' do + describe '#software_records' do + let(:software_records) { SoftwareRecords.new } + + before do + FactoryBot.create(:software_record, tech_leads: nil, departments: nil, developers: nil, + product_owners: nil, admin_users: nil) + end + + it 'exports CSV with appropriate headers' do + csv_content = File.read("#{Dir.pwd}/public/software_records.csv") + headers = [ + 'Software Record', 'Description', 'Status', 'Created on', 'Software Type', + 'Authentication Type', 'Vendor Record', 'Departments', 'Date Implemented', + 'Date of upgrade', 'Developers', 'Tech Leads', 'Product Owners', + 'Admin Users', 'Languages Used', 'Production URL', 'Source Code URL', + 'User Seats', 'Annual Fees', 'Support Contract', 'Hosting Environment', + 'Current Version', 'Notes', 'Business Value', 'IT Quality', 'Created By', + 'Requires Change Management review?', 'Last Security Scan', + 'Last Accessibility Scan', 'Last OGC Review', 'Last Infosec Review', + 'CM Stakeholders', 'CM Other Notes', 'QA URL', 'Dev_URL', 'Prod_URL', + 'Production Support Servers', 'Last Record Change', 'Track Uptime', + 'Monitor Health', 'Monitor Errors' + ] + + expect(CSV.parse(csv_content, headers: true).headers).to eq(headers) + end + + it 'includes nil attributes as empty fields' do + csv_content = File.read("#{Dir.pwd}/public/software_records.csv") + csv_rows = CSV.parse(csv_content, headers: true) + + csv_rows.each do |row| + expect(row['Tech Leads']).to eq('') + expect(row['Departments']).to eq('') + expect(row['Developers']).to eq('') + expect(row['Product Owners']).to eq('') + expect(row['Admin Users']).to eq('') + end + end end end diff --git a/spec/factories/software_records.rb b/spec/factories/software_records.rb index 15da1447..9abfc5e4 100644 --- a/spec/factories/software_records.rb +++ b/spec/factories/software_records.rb @@ -14,5 +14,32 @@ software_type_id { SoftwareType.first.id } hosting_environment_id { HostingEnvironment.first.id } created_by { 'Test User' } + authentication_type { 'Sample Authentication Type' } + date_of_upgrade { Date.today } + languages_used { 'Ruby, Python' } + production_url { 'http://example.com' } + source_code_url { 'http://github.com' } + user_seats { 10 } + annual_fees { 1000.0 } + support_contract { 'Standard Support' } + current_version { '1.0.0' } + notes { 'Sample notes' } + business_value { 'High' } + it_quality { 'Good' } + requires_cm { true } + last_security_scan { Date.today } + last_accessibility_scan { Date.today } + last_ogc_review { Date.today } + last_info_sec_review { Date.today } + cm_stakeholders { 'Stakeholder 1' } + cm_other_notes { 'No additional notes' } + qa_url { 'http://qa.example.com' } + dev_url { 'http://dev.example.com' } + prod_url { 'http://prod.example.com' } + production_support_servers { 'Server 1, Server 2' } + last_record_change { Date.today } + track_uptime { true } + monitor_health { true } + monitor_errors { true } end end