Initial commit
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
require 'spec_helper'
|
||||
require 'support/factories/users'
|
||||
require 'helpers/named_maps_helper'
|
||||
|
||||
describe Carto::DataExporter do
|
||||
include CartoDB::Factories
|
||||
include NamedMapsHelper
|
||||
|
||||
describe '#export_tables' do
|
||||
include_context 'user helper'
|
||||
|
||||
# INFO: this needs SQL API configured for testing
|
||||
it 'exports a table in requested format' do
|
||||
table_name = 'table1'
|
||||
table = create_table(name: table_name, user_id: @user.id)
|
||||
user_table = Carto::UserTable.find_by_table_id(table.get_table_id)
|
||||
table.insert_row!(id: 666, description: 'desc', name: 'a row')
|
||||
|
||||
format = 'shp'
|
||||
|
||||
tmp_dir = "/tmp/export_test_#{String.random(15)}"
|
||||
FileUtils.mkdir_p tmp_dir
|
||||
|
||||
begin
|
||||
Carto::Http::Request.any_instance.stubs(:run)
|
||||
file = File.new(Carto::DataExporter.new.export_table(user_table, tmp_dir, format))
|
||||
file.path.should match(/.#{format}$/)
|
||||
file.close
|
||||
ensure
|
||||
File.delete file if file
|
||||
FileUtils.rm_rf tmp_dir
|
||||
table.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Carto::VisualizationExport do
|
||||
include Carto::ExporterConfig
|
||||
include_context 'users helper'
|
||||
include Carto::Factories::Visualizations
|
||||
|
||||
class FakeCartoHttpClientFileToucher
|
||||
attr_reader :touched_files
|
||||
|
||||
def initialize
|
||||
@touched_files = []
|
||||
end
|
||||
|
||||
# Mock needs not url nor Typhoeus options
|
||||
def get_file(_, exported_file, _)
|
||||
@touched_files << exported_file
|
||||
touch(exported_file)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def random_filename(dir, extension: 'shp')
|
||||
"#{dir}/test_#{String.random(12)}.#{extension}".downcase
|
||||
end
|
||||
|
||||
def touch_random_filename(dir, extension: 'shp')
|
||||
touch(random_filename(dir, extension: extension))
|
||||
end
|
||||
|
||||
def touch(path)
|
||||
FileUtils.touch(path).first
|
||||
end
|
||||
end
|
||||
|
||||
let(:base_dir) { ensure_clean_folder('/tmp/exporter_test') }
|
||||
|
||||
describe '#export' do
|
||||
it 'exports a .carto file including the carto.json and the files' do
|
||||
map = FactoryGirl.create(:carto_map, user: @carto_user1)
|
||||
|
||||
table1 = FactoryGirl.create(:private_user_table, user: @carto_user1)
|
||||
table2 = FactoryGirl.create(:private_user_table, user: @carto_user1)
|
||||
|
||||
layer1 = FactoryGirl.create(:carto_layer, options: { table_name: table1.name }, maps: [map])
|
||||
FactoryGirl.create(:carto_layer, options: { table_name: table2.name }, maps: [map])
|
||||
|
||||
map, table, table_visualization, visualization = create_full_visualization(@carto_user1,
|
||||
map: map,
|
||||
table: table1,
|
||||
data_layer: layer1)
|
||||
|
||||
fake_carto_http_client_toucher = FakeCartoHttpClientFileToucher.new
|
||||
|
||||
exported_file = Carto::VisualizationExport.new.export(
|
||||
visualization,
|
||||
@carto_user1,
|
||||
base_dir: base_dir,
|
||||
data_exporter: Carto::DataExporter.new(fake_carto_http_client_toucher))
|
||||
|
||||
touched_files = fake_carto_http_client_toucher.touched_files
|
||||
CartoDB::Importer2::Unp.new.open(exported_file) do |files|
|
||||
files.length.should eq (map.layers.count + 1)
|
||||
names = files.map(&:path)
|
||||
names.count { |f| f =~ /\.carto\.json$/ }.should eq 1
|
||||
names.should include(touched_files[0].split('/').last)
|
||||
names.should include(touched_files[1].split('/').last)
|
||||
end
|
||||
|
||||
([exported_file] + touched_files).map { |f| File.delete(f) if File.exists?(f) }
|
||||
|
||||
destroy_full_visualization(map, table, table_visualization, visualization)
|
||||
end
|
||||
|
||||
it 'excludes data not accessible by the user' do
|
||||
map = FactoryGirl.create(:carto_map, user: @carto_user1)
|
||||
|
||||
table1 = FactoryGirl.create(:private_user_table, user: @carto_user1)
|
||||
|
||||
layer1 = FactoryGirl.create(:carto_layer, options: { table_name: table1.name }, maps: [map])
|
||||
|
||||
map, table, table_visualization, visualization = create_full_visualization(@carto_user1,
|
||||
map: map,
|
||||
table: table1,
|
||||
data_layer: layer1)
|
||||
|
||||
fake_carto_http_client_toucher = FakeCartoHttpClientFileToucher.new
|
||||
|
||||
exported_file = Carto::VisualizationExport.new.export(
|
||||
visualization,
|
||||
@carto_user2,
|
||||
base_dir: base_dir,
|
||||
data_exporter: Carto::DataExporter.new(fake_carto_http_client_toucher))
|
||||
|
||||
touched_files = fake_carto_http_client_toucher.touched_files
|
||||
CartoDB::Importer2::Unp.new.open(exported_file) do |files|
|
||||
files.length.should eq 1 # visualization export
|
||||
names = files.map(&:path)
|
||||
names.count { |f| f =~ /\.carto\.json$/ }.should eq 1
|
||||
end
|
||||
|
||||
([exported_file] + touched_files).map { |f| File.delete(f) if File.exists?(f) }
|
||||
|
||||
destroy_full_visualization(map, table, table_visualization, visualization)
|
||||
end
|
||||
|
||||
it 'excludes layers and user_tables with user_tables_ids parameter' do
|
||||
map = FactoryGirl.create(:carto_map, user: @carto_user1)
|
||||
|
||||
table1 = FactoryGirl.create(:private_user_table, user: @carto_user1)
|
||||
table2 = FactoryGirl.create(:private_user_table, user: @carto_user1)
|
||||
|
||||
layer1 = FactoryGirl.create(:carto_layer, options: { table_name: table1.name }, maps: [map])
|
||||
FactoryGirl.create(:carto_layer, options: { table_name: table2.name }, maps: [map])
|
||||
|
||||
map, table, table_visualization, visualization = create_full_visualization(@carto_user1,
|
||||
map: map,
|
||||
table: table1,
|
||||
data_layer: layer1)
|
||||
|
||||
fake_carto_http_client_toucher = FakeCartoHttpClientFileToucher.new
|
||||
|
||||
exported_file = Carto::VisualizationExport.new.export(
|
||||
visualization,
|
||||
@carto_user1,
|
||||
user_tables_ids: [table1.id],
|
||||
base_dir: base_dir,
|
||||
data_exporter: Carto::DataExporter.new(fake_carto_http_client_toucher))
|
||||
|
||||
touched_files = fake_carto_http_client_toucher.touched_files
|
||||
CartoDB::Importer2::Unp.new.open(exported_file) do |files|
|
||||
files.length.should eq (1 + 1) # selected user_table + metadata
|
||||
names = files.map(&:path)
|
||||
names.count { |f| f =~ /\.carto\.json$/ }.should eq 1
|
||||
names.should include(touched_files[0].split('/').last)
|
||||
touched_files.length.should eq 1
|
||||
end
|
||||
|
||||
([exported_file] + touched_files).map { |f| File.delete(f) if File.exists?(f) }
|
||||
|
||||
destroy_full_visualization(map, table, table_visualization, visualization)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#run_export!' do
|
||||
# run_export! is called from the job, but the core of the logic is in `#export`, this makes sure its usage
|
||||
it 'calls #export' do
|
||||
visualization = FactoryGirl.create(:carto_visualization, user: @carto_user1)
|
||||
ve = FactoryGirl.create(:visualization_export, user: @carto_user1, visualization: visualization)
|
||||
|
||||
fake_path = "/tmp/fakepath"
|
||||
touch(fake_path)
|
||||
ve.expects(:export).returns(fake_path)
|
||||
file_upload_helper_mock = mock
|
||||
file_upload_helper_mock.expects(:upload_file_to_storage)
|
||||
|
||||
ve.run_export!(file_upload_helper: file_upload_helper_mock)
|
||||
|
||||
visualization.destroy
|
||||
File.delete(fake_path) if File.exists?(fake_path)
|
||||
end
|
||||
|
||||
describe 'with S3' do
|
||||
before(:each) do
|
||||
@visualization = FactoryGirl.create(:carto_visualization, user: @carto_user1)
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
@visualization.destroy
|
||||
end
|
||||
|
||||
let(:test_dir) { '/tmp/exports_test/' }
|
||||
let(:fake_path) { "#{test_dir}/fake_export.carto" }
|
||||
|
||||
it 'runs export creating a log trace' do
|
||||
ve = Carto::VisualizationExport.new(visualization: @visualization, user: @carto_user1)
|
||||
|
||||
FileUtils.mkdir_p test_dir
|
||||
FileUtils.touch(fake_path).first
|
||||
ve.expects(:export).returns(fake_path)
|
||||
|
||||
file_upload_helper_mock = mock
|
||||
file_upload_helper_mock.expects(:upload_file_to_storage).returns(file_url: fake_path)
|
||||
|
||||
ve.run_export!(file_upload_helper: file_upload_helper_mock)
|
||||
ve.reload
|
||||
|
||||
ve.log.should_not be_nil
|
||||
ve.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user