Skip to content

Commit

Permalink
Remove support for local files
Browse files Browse the repository at this point in the history
This streamlines the task to focus only on remote URLs, which also means that some fixtures go away and get replaced by new cassettes.
  • Loading branch information
matt-bernhardt committed Aug 7, 2024
1 parent 7ac80bf commit 8887859
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 63 deletions.
4 changes: 2 additions & 2 deletions app/models/detector/suggested_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ def self.bulk_replace(input)
raise ArgumentError.new, 'Tabular CSV is required' unless input.instance_of?(CSV::Table)

# Need to check what columns exist in input
required_headers = %i[title url phrase]
required_headers = %w[Title URL Phrase]
missing_headers = required_headers - input.headers
raise ArgumentError.new, "Some CSV columns missing: #{missing_headers}" unless missing_headers.empty?

Detector::SuggestedResource.delete_all

input.each do |line|
record = Detector::SuggestedResource.new({ title: line[:title], url: line[:url], phrase: line[:phrase] })
record = Detector::SuggestedResource.new({ title: line['Title'], url: line['URL'], phrase: line['Phrase'] })
record.save
end
end
Expand Down
37 changes: 10 additions & 27 deletions lib/tasks/suggested_resources.rake
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,23 @@ namespace :suggested_resources do
# we do need a way to import records from a CSV file.
desc 'Replace all Suggested Resources from CSV'
task :reload, [:addr] => :environment do |_task, args|
raise ArgumentError.new, 'File is required' unless args.addr.present?
raise ArgumentError.new, 'URL is required' unless args.addr.present?

raise ArgumentError.new, 'Local files are not supported yet' unless URI(args.addr).scheme

Rails.logger.info('Reloading all Suggested Resource records from CSV')
Rails.logger.info("Record count before we reload: #{Detector::SuggestedResource.count}")

if URI(args.addr).scheme
url = URI.parse(args.addr)
raise ArgumentError.new, 'HTTP/HTTPS scheme is required' unless url.scheme.in?(%w[http https])
url = URI.parse(args.addr)

data = csv_table_from_url_direct(url)
else
file = File.open(args.addr)
# Invalid / not found file should ... do something?
data = CSV.table(file)
end
raise ArgumentError.new, 'HTTP/HTTPS scheme is required' unless url.scheme.in?(%w[http https])

Detector::SuggestedResource.bulk_replace(data)
file = url.open.read.gsub("\xEF\xBB\xBF", '').force_encoding('UTF-8').encode
data = CSV.parse(file, headers: true)

Rails.logger.info("Record count after we reload: #{Detector::SuggestedResource.count}")
end
Rails.logger.info("Record count before we reload: #{Detector::SuggestedResource.count}")

def csv_table_from_url_direct(url)
file = url.open.read.force_encoding('UTF-8').encode
csv = CSV.parse(file, headers: true)
end
Detector::SuggestedResource.bulk_replace(data)

def csv_table_from_url_rebuild(url)
file = url.read
all_rows = CSV.new(file).read
header = []
all_rows[0].each { |field| header.push(field.strip.downcase.gsub("\xEF\xBB\xBF".force_encoding("UTF-8"), '').to_sym) }
value_rows = all_rows.length - 1
values = all_rows[1..value_rows]
rebuild = values.map { |row| CSV::Row.new(header, row) }
CSV::Table.new(rebuild)
Rails.logger.info("Record count after we reload: #{Detector::SuggestedResource.count}")
end
end
Binary file removed test/fixtures/files/suggested_resources.xlsx
Binary file not shown.
3 changes: 0 additions & 3 deletions test/fixtures/files/suggested_resources_extra.csv

This file was deleted.

3 changes: 0 additions & 3 deletions test/fixtures/files/suggested_resources_missing_field.csv

This file was deleted.

2 changes: 0 additions & 2 deletions test/fixtures/files/suggested_resources_wrong_columns.csv

This file was deleted.

55 changes: 35 additions & 20 deletions test/tasks/suggested_resource_rake_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,60 @@ def setup
Rake::Task['suggested_resources:reload'].reenable
end

test 'invoked reload can accept a local file' do
test 'reload can accept a url' do
records_before = Detector::SuggestedResource.count # We have three fixtures at the moment
first_record_before = Detector::SuggestedResource.first
local_file = Rails.root.join('test','fixtures','files','suggested_resources.csv').to_s
Rake::Task["suggested_resources:reload"].invoke(local_file)
VCR.use_cassette('suggested_resource:reload from remote csv') do
remote_file = 'http://static.lndo.site/suggested_resources.csv'
Rake::Task['suggested_resources:reload'].invoke(remote_file)
end
refute_equal records_before, Detector::SuggestedResource.count
refute_equal first_record_before, Detector::SuggestedResource.first
end

test 'reload task errors without a file argument' do
assert_raises(ArgumentError) {
error = assert_raises(ArgumentError) do
Rake::Task['suggested_resources:reload'].invoke
}
end
assert_equal 'URL is required', error.message
end

test 'reload can accept a url' do
VCR.use_cassette('remote csv') do
remote_file = 'http://static.lndo.site/suggested_resources.csv'
Rake::Task["suggested_resources:reload"].invoke(remote_file)
test 'reload errors on a local file' do
error = assert_raises(ArgumentError) do
local_file = Rails.root.join('test', 'fixtures', 'files', 'suggested_resources.csv').to_s
Rake::Task['suggested_resources:reload'].invoke(local_file)
end
assert_equal 'Local files are not supported yet', error.message
end

test 'reload fails with a non-CSV file' do
local_file = Rails.root.join('test','fixtures','files','suggested_resources.xlsx').to_s
assert_raises(CSV::MalformedCSVError) {
Rake::Task['suggested_resources:reload'].invoke(local_file)
}
assert_raises(CSV::MalformedCSVError) do
VCR.use_cassette('suggested_resource:reload from remote non-csv') do
remote_file = 'http://static.lndo.site/suggested_resources.xlsx'
Rake::Task['suggested_resources:reload'].invoke(remote_file)
end
end
end

test 'reload fails unless all three columns are present: title, url, phrase' do
local_file = Rails.root.join('test','fixtures','files','suggested_resources_missing_field.csv').to_s
error = assert_raises(ArgumentError) {
Rake::Task['suggested_resources:reload'].invoke(local_file)
}
assert_equal 'Some CSV columns missing: [:phrase]', error.message
error = assert_raises(ArgumentError) do
VCR.use_cassette('suggested_resource:reload with missing field') do
remote_file = 'http://static.lndo.site/suggested_resources_missing_field.csv'
Rake::Task['suggested_resources:reload'].invoke(remote_file)
end
end
assert_equal 'Some CSV columns missing: ["Phrase"]', error.message
end

# assert_nothing_raised is viewed as an anti-pattern, but I'm leery of a test
# with no assertions. As a result, we use a single assertion to confirm
# something happened.
test 'reload succeeds if extra columns are present' do
local_file = Rails.root.join('test','fixtures','files','suggested_resources_extra.csv').to_s
Rake::Task['suggested_resources:reload'].invoke(local_file)
records_before = Detector::SuggestedResource.count # We have three fixtures at the moment
VCR.use_cassette('suggested_resource:reload with extra field') do
remote_file = 'http://static.lndo.site/suggested_resources_extra.csv'
Rake::Task['suggested_resources:reload'].invoke(remote_file)
end
refute_equal records_before, Detector::SuggestedResource.count
end
end

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8887859

Please sign in to comment.