Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

495 export to excel does not work if components have the same name #505

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ group :test do
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'

gem 'database_cleaner-active_record'
gem 'rubocop', require: false
gem 'rubocop-performance'
gem 'rubocop-rails'
Expand Down
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ GEM
coderay (1.1.3)
concurrent-ruby (1.1.9)
crass (1.0.6)
database_cleaner-active_record (2.0.1)
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
devise (4.8.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
Expand Down Expand Up @@ -462,6 +466,7 @@ DEPENDENCIES
brakeman
byebug
capybara (>= 2.15)
database_cleaner-active_record
devise
factory_bot_rails (~> 5.2.0)
fast_excel
Expand Down
3 changes: 2 additions & 1 deletion app/helpers/export_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def export_excel(project)
srg_rule: %i[disa_rule_descriptions rule_descriptions checks]
}]
).each do |component|
worksheet = workbook.add_worksheet(component[:name])
worksheet_name = "#{component[:name]}-V#{component[:version]}R#{component[:release]}-#{component[:id]}"
worksheet = workbook.add_worksheet(worksheet_name)
worksheet.auto_width = true
worksheet.append_row(ExportConstants::DISA_EXPORT_HEADERS)
last_row_num = 0
Expand Down
8 changes: 4 additions & 4 deletions app/models/rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,15 @@ def csv_attributes
SEVERITIES_MAP[rule_severity] || rule_severity,
srg_rule.title, # original srg title
title,
srg_rule.disa_rule_descriptions.first.vuln_discussion, # original srg vuln discussion
disa_rule_descriptions.first.vuln_discussion,
srg_rule.disa_rule_descriptions.first&.vuln_discussion, # original srg vuln discussion
disa_rule_descriptions.first&.vuln_discussion,
status,
srg_rule.checks.first.content, # original SRG check content
srg_rule.checks.first&.content, # original SRG check content
export_checktext,
srg_rule.fixtext, # original SRG fix text
export_fixtext,
status_justification,
disa_rule_descriptions.first.mitigations,
disa_rule_descriptions.first&.mitigations,
artifact_description,
vendor_comments_with_satisfactions
]
Expand Down
24 changes: 24 additions & 0 deletions spec/factories/components.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

FactoryBot.define do
factory :component do
project { create(:project) }
based_on { create(:security_requirements_guide) }

prefix { 'ABCD-00' }
name { FFaker::Name.name }
admin_name { generate(:name) }
admin_email { generate(:email) }
advanced_fields { false }
version { generate(:version) }
release { generate(:release) }
title { 'Fake title' }
description { 'Fake description' }

trait :released_component do
released { true }
end

factory :released_component, traits: [:released_component]
end
end
7 changes: 7 additions & 0 deletions spec/factories/projects.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

FactoryBot.define do
factory :project do
name { generate(:name) }
end
end
13 changes: 13 additions & 0 deletions spec/factories/security_requirements_guides.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

XML_FILE = File.read('./spec/fixtures/files/U_Web_Server_V2R3_Manual-xccdf.xml')

FactoryBot.define do
factory :security_requirements_guide do
srg_id { FFaker::Name.name.underscore }
title { FFaker::Name.name }
version { "V#{rand(0..9)}R#{rand(0..9)}" }
xml { XML_FILE }
release_date { Time.zone.today }
end
end
3 changes: 3 additions & 0 deletions spec/factories/sequences.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@
sequence(:name) { |n| "John Doe#{n}" }
sequence(:email) { |n| "user#{n}@example.org" }
sequence(:password) { |n| "12345678#{n}" }
sequence(:version) { |n| n }
sequence(:release) { |n| n }
sequence(:rule_id) { |n| n.to_s.rjust(6, '0') }
end
126 changes: 126 additions & 0 deletions spec/helpers/export_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe ExportHelper, type: :helper do
include ExportHelper

before(:all) do
@component = FactoryBot.create(:component)
@released_component = FactoryBot.create(:released_component)
@project = @component.project
@project_with_realeased_comp = @released_component.project
end

describe '#export_excel' do
before(:all) do
@workbook = export_excel(@project)
@workbook_release = export_excel(@project_with_realeased_comp)

[@workbook, @workbook_release].each_with_index do |item, index|
file_name = ''
if index == 0
file_name = "./#{@project.name}.xlsx"
File.binwrite(file_name, item.read_string)
@xlsx = Roo::Spreadsheet.open(file_name)
else
file_name = "./#{@project_with_realeased_comp.name}.xlsx"
File.binwrite(file_name, item.read_string)
@xlsx_release = Roo::Spreadsheet.open(file_name)
end
File.delete(file_name)
end
end

context 'in all scenarios' do
it 'creates an excel format of a given project' do
expect(@workbook).to be_present
expect(@workbook.filename).to end_with 'xlsx'
end
end

context 'when project has released component' do
it 'creates an excel file with the # of sheets == # of released components' do
expect(@xlsx_release.sheets.size).to eq @project_with_realeased_comp.components.where(released: true).size
end

it 'creates an excel file with correct format for worksheet name' do
sheet_name = "#{@released_component.name}-V#{@released_component.version}"
sheet_name += "R#{@released_component.release}-#{@released_component.id}"
expect(@xlsx_release.sheets).to include(sheet_name)
end
end

context 'when project has no released component' do
it 'creates an empty spreadsheet' do
expect(@xlsx.sheets.size).to eq 1
expect(@xlsx.sheets.first).to eq 'Sheet1'
end
end
end

describe '#export_xccdf' do
before(:all) do
@file_name = "./#{@project.name}.zip"
File.binwrite(@file_name, export_xccdf(@project).string)
@zip = Zip::File.open(@file_name)
end

after(:all) do
File.delete(@file_name)
end

it 'creates a zip file containing all components of a project in xccdf format' do
expect(@zip.size).to eq @project.components.size
# check the content of each file is valid xml
errors = []
@zip.each do |xml|
xml.get_input_stream { |io| errors << Nokogiri::XML(io.read).errors }
end
expect(errors).to all(be_empty)
end

it 'creates a zip file containing xccdf files with correct name format' do
expected_names = @project.components.map do |comp|
version = comp.version ? "V#{comp.version}" : ''
release = comp.release ? "R#{comp.release}" : ''
title = (comp.title || "#{comp.name} STIG Readiness Guide")
"U_#{title.tr(' ', '_')}_#{version}#{release}-xccdf.xml"
end
expect(@zip.map(&:name).sort).to eq expected_names.sort
end
end

describe '#export_inspec_project' do
before(:all) do
@file_name = "./#{@project.name}.zip"
File.binwrite(@file_name, export_inspec_project(@project).string)
@zip = Zip::File.open(@file_name)
end

after(:all) do
File.delete(@file_name)
end

it 'creates a zip file containing all components of a project in YAML format' do
expect(@zip.size).to eq @project.components.size
# ensure files are valid yaml
@zip.each do |yml|
content = nil
yml.get_input_stream { |io| content = io.read }
expect { YAML.parse(content) }.to_not raise_error
end
end

it 'creates a zip file containing yaml files with correct name format' do
expected_names = @project.components.map do |comp|
version = comp.version ? "V#{comp.version}" : ''
release = comp.release ? "R#{comp.release}" : ''

"#{comp.name.tr(' ', '-')}-#{version}#{release}-stig-baseline/inspec.yml"
end

expect(@zip.map(&:name).sort).to eq expected_names.sort
end
end
end
17 changes: 17 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"

# configure database cleaner
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end

config.before(:each) do
DatabaseCleaner.strategy = :transaction
end

config.before(:each) do
DatabaseCleaner.start
end

config.after(:each) do
DatabaseCleaner.clean
end

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
Expand Down